CSS width transition and hover - css

I'm trying to implement a slide show like menu with CSS. It's working fine except for transition. If transition is used the elements are not in sync anymore. Whole menu losing width if multiple elements are hovered in short time. Everything works fine if transition is removed.
Is there anything I have to be aware of when using CSS transitions and hover together? I thought a transition-timing-function: linear; would be enough to get width in sync. It seems like the transition is started early on the fading out element than fading in element.
Some technical notes about implementation:
It's a ul list. Menu items are represented as li. Selected menu item has a selected. This one is shown if there isn't any user interaction. The other ones are collapsed. If an element is hovered it's opened and all other ones are collapsed. There should be a transition effect when changing from collapsed to shown.
ul {
list-style: none;
display: inline-block;
padding: 0;
/*
* remove gaps between inline elements
* https://css-tricks.com/fighting-the-space-between-inline-block-elements/
*/
font-size: 0;
}
ul li {
display: inline-block;
overflow: hidden;
/*
* Transition
*/
transition: width 0.5s;
transition-timing-function: linear;
width: 50px;
}
ul li:hover,
ul li.selected,
ul:hover li.selected:hover {
width: 564px;
}
ul:hover li.selected {
width: 50px;
}
<ul>
<li>
<a href="http://www.3ker-ras-group.com/profil.html">
<img src="http://www.3ker-ras-group.com/images/m_profil.jpg" alt="Unser Profil">
</a>
</li>
<li class="selected">
<a href="http://www.3ker-ras-group.com/referenzen.html">
<img src="http://www.3ker-ras-group.com/images/m_referenzen_der_3ker_ras_group.jpg" alt="Referenzen der 3KER RAS GROUP">
</a>
</li>
<li>
<a href="http://www.3ker-ras-group.com/jobs.html">
<img src="http://www.3ker-ras-group.com/images/m_hoehenarbeiter_jobs.jpg" alt="Jobs für Höhenarbeiter">
</a>
</li>
<li>
<a href="http://www.3ker-ras-group.com/shop-kletterbedarf.html">
<img src="http://www.3ker-ras-group.com/images/m_kletterbedarf_shop.jpg" alt="Unser Shop für Kletterbedarf">
</a>
</li>
<li>
<a href="http://www.3ker-ras-group.com/kontakt.html">
<img src="http://www.3ker-ras-group.com/images/m_kontakt_zum_unternehmen.jpg" alt="Kontakt aufnehmen">
</a>
</li>
</ul>
Trigger the issue by moving cursor fast from left to right. It occurs at least in Firefox and Chrome. Didn't tested safari, IE and edge.
Here is a JSFiddle: https://jsfiddle.net/vj12qswz/3/
All elements should fit in one line. Adjust preview window width if necessary.

Works fine if you use javascript to add a specific class on hover.
Probably best to add "onclick" event as well because hover not gonna work on touch devices.

Related

Chrome glitch and Hover event

i have a weird problem with Chrome only. I have a menu on my website with a submenu that shows only when parent item get hovered.
Here's my CSS :
.menu .liFirstLevel ul
{
position: relative;
background-image: url(/imgs/bg-submenu.jpg);
background-repeat: repeat;
}
.menu .liFirstLevel:hover ul {
display: block;
z-index: 5;
padding: 0px;
line-height: 30px;
}
Here's the problem : Lets supppose that i have a parent menu with a submenu that contains 3 options. Like this :
<ul class='menu'>
<li class='liFirstLevel'>
<ul class='submenu'>
<li>SubMenu1</li>
<li>SubMenu2</li>
<li>SubMenu3</li>
</ul>
</li>
</ul>
When i hover the ul.menu, the submenu always display, as supposed to. But when i try to select one of the subitem menu, it disapear as soon as the crusor is at the middle height of the first subitem... So in the exemple above, As soon as i reach the middle height of "Submenu1" my submenu disapear. Now here's the strange part : If i minimize chrome and then bring it back, the bug is gone...
My menu is 100% functionnal. So i'm pretty sure my CSS is ok...
Any ideas of what i can try ? I tried so many things.
I hope i'm clear, it's a bit complex to explain !
Thanks

Color overlay a responsive image with Compass?

I don't have control over the HTML that I'm styling, so each img is nested in an li. The li has padding, which cannot be changed to a margin because of a complex responsive grid system. And, yes, since it's responsive, the size of the image might change.
Here's the demo: Play with this gist on SassMeister.
Sass:
.active {
border: grey solid 4px;
opacity: .2;
}
ul {
list-style:none;
}
li {
width: 20%;
padding: 5%;
display: inline-block;
}
img {
width: 100%;
}
#thumbs {
width: 100%;
}
HTML:
<div id="thumbs">
<ul>
<li>
<img class="active" src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQvXOVCJkz-VEZjmFxh0dgKUZ5z6Ojg7doS64g8FUmDsdEE-6_R">
</li>
<li>
<img src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQvXOVCJkz-VEZjmFxh0dgKUZ5z6Ojg7doS64g8FUmDsdEE-6_R">
</li>
<li>
<img src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQvXOVCJkz-VEZjmFxh0dgKUZ5z6Ojg7doS64g8FUmDsdEE-6_R">
</li>
</ul>
</div>
How can I make a color overlay effect on the .active image?
Background color applied to the li parent is messy because of the padding, and I am having trouble figuring out how to create a pseudo element that's the same size as the image.
Edit: I thought maybe I could achieve this with an offset border, see this gist on SassMeister. But I would need to do some math to make the border width and offset exactly half the width (or height) of the image. Can I do that with Sass?
Sass:
.active {
border: grey solid 4px;
opacity: .2;
outline: 160px solid rgba(255,0,0,0.7);
outline-offset: -160px;
}
ul {
list-style:none;
}
li {
width: 20%;
padding: 5%;
display: inline-block;
}
img {
width: 100%;
}
#thumbs {
width: 100%;
}
HTML:
<div id="thumbs">
<ul>
<li>
<img class="active" src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQvXOVCJkz-VEZjmFxh0dgKUZ5z6Ojg7doS64g8FUmDsdEE-6_R">
</li>
<li>
<img src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQvXOVCJkz-VEZjmFxh0dgKUZ5z6Ojg7doS64g8FUmDsdEE-6_R">
</li>
<li>
<img src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQvXOVCJkz-VEZjmFxh0dgKUZ5z6Ojg7doS64g8FUmDsdEE-6_R">
</li>
</ul>
</div>
I got something working, try this on for size. It only works if you can add a class to the <li>.
Unfortunately, CSS doesn't allow any form of parent selection, so you can't say 'give me any <li> containing an <img> with the class <active> :( That's javascript turf
Unless you want to stuff around adding overlays with javascript, why not apply the tint color you want to the parent element <li>, then replace the padding with margins so the colour doesn't stick out, as it's obscured by the image within. Then apply the opacity to the img.active like you have. I think you were on the right track with the first idea.
The only control you really get over opacity is either the element itself or it's background color, as in rgba(red, blue, green, opacity). This means if you apply the BG colour to the image, it will be obscured by this image, and as any changes to transparency effect the whole thing.

List bullet alignment changes when LI contains a block-level empty element

I hope someone can explain this odd CSS issue I'm encountering.
I have an empty element (think <img> or <input>) inside a li. When I change the display style on the empty element to "block", the alignment of the bullet on the li changes. If I do the same thing with a non-empty element (<span>, say), the bullet alignment does not change.
The bullet alignment changes even if the empty element is inside another block-level element (<div>).
Here are two examples on JSFiddle:
Using an <img> element
Using a <span> element
And screenshots of the results (<img> on the left, <span> on the right:
I have two questions:
Why do the bullets do this?
How can I make the bullets in the <img> example line up the same way as in the <span> example?
For reference, the stylesheet:
ul { background: lightgreen; width: 100px; padding-left: 50px; }
div { background: lightblue; }
img { background: lightcoral; }
li { background: lightyellow; }
img { width: 50px; height: 50px; }
img[rel] { display: block; }
And the HTML:
<ul>
<li>
<div><img rel></div>
</li>
</ul>
<ul>
<li>
<div><img></div>
</li>
</ul>
<ul>
<li>
<div><img rel></div>
<p> ! </p>
</li>
</ul>
<ul>
<li>
<div><img></div>
<p> ! </p>
</li>
</ul>
(I know my <img> elements don't have src attributes. This is just for illustration purposes. BTW, it still works in Google Chrome, but not Firefox.)
It is an issue with alignment for images, they default to the bottom alignment which causes the list items to move with them. In order to fix this problem, add this to the image tag:
img {
display: inline-block;
vertical-align: middle;
}
The display: inline-block is the only display type that will allow vertical align to work.

Large whitespace caused by hidden li items?

I've got a menu that pops out of a list item. Something to this effect:
<li>
<ul class="topmenu">
<li class="submenu">
<a class="otherIT" href="#" title="Common IT Tasks"><img src="./images/ittasks.png" alt="Common IT Tasks" /></a>
<a class="otherIT" href="#" title="Common IT Tasks">Other - Common IT Tasks</a>
<p>Most common IT tasks.</p>
<ul class="subsubmenu">
<li>
Log a ticket
</li>
<li>
Map drives
</li>
<li>
Unlock a user
</li>
</ul>
</li>
</ul>
</li>
Immediately underneath this li item I have this:
<li class="break">
Back to top
</li>
When I don't hover over the li item it gives me this effect:
When I hover over this li item it gives me this effect:
Great the menu works, my issue is the gap between the word "Back to top" with the li item, it is fairly large. I believe it is due to the invisible li items of the list. For anyone interested, the CSS is something to this effect:
ul.topmenu, ul.topmenu ul {
display: block;
margin: 0;
padding: 0;
}
ul.topmenu li {
display: inline;
list-style: none;
margin: 0;
padding-right: 1.5em;
}
ul.topmenu li ul {
visibility: hidden; }
ul.topmenu li.submenu:hover ul {
visibility: visible;
}
Simple classic visibility is hidden unless you hover, however, the whitespace between the word "Back to top" with the list item is too large.
visibility: hidden only makes the element invisible, but does not remove it from the page flow.
display: none will hide the element and remove it from the page flow (so it won't take up any space or affect other elements in any way).
visibility : hidden only makes the element invisible, but does not remove it from the page flow. display: none will hide the element and remove it from the page flow (so it won't take up any space or affect other elements in any way)
ul.topmenu li ul
{
display: none;
}
ul.topmenu li.submenu:hover ul
{
display: block;
}
visibility:hidden do not show element, but still reserves space for it.
Try display:none
Use the CSS display: none rule instead of visibilty: hidden, because you want your tag to not be displayed at all, you don't want a blank space allocated in it's place (see). From the W3 docs:
Please note that a display of 'none' does not create an invisible box; it creates no box at all. CSS includes mechanisms that enable an element to generate boxes in the formatting structure that affect formatting but are not visible themselves.
Also, what does the W3 validator say about your HTML?

Dropdown Menu - Make the <ul> submenu 100% width

I am going a bit crazy trying to achieve something my client wants. I could tell them it's not possible but I love a good challenge ;)
Basically, I'm trying to do a dropdown menu in which the dropdown <ul>, or:
ul.menu li ul
is surrounded by a div. Kind of:
<ul class="menu">
<li>
Item
<div class="submenu">
<ul>.....</ul>
</div>
</li>
</ul>
I want that div to have width:100% and fill the whole width of the page but have the UL inside aligned to the appropriate <li>.
The problem is the <div class="submenu"> will be as wide as the relative container, be it the main <ul class="menu"> or a <div> wrapping the <ul class="menu">.
The website itself has 1000px width and is centered width margin:0 auto;
I hope I have explained myself properly :S Here is a link to a mock up I have put together: Dropdown Menu Mock up
Any help highly appreciated.
Thanks,
Alex
Old question, but hopefully answer will help someone. I had to work on something similar to this a month or so ago.
Here is a fiddle of what I basically did (note: you have to do some extra work for this to work the same in older IEs): http://jsfiddle.net/doubleswirve/xbLrW/2/
I didn't use a nested div and instead stuck with nested lists. With a basic markup like the following:
<div class="nav">
<ul>
<li>
Products
<ul>
<li>Widget A</li>
<li>Widget B</li>
<li>Widget C</li>
</ul>
</li>
<li>
Locations
<ul>
<li>Location A</li>
<li>Location B</li>
<li>Location C</li>
</ul>
</li>
<li>
Staff
<ul>
<li>President</li>
<li>VP</li>
<li>Manager</li>
</ul>
</li>
</ul>
</div>
You can use the following styling:
/* GENERAL */
body { overflow-x: hidden; } /* trick from css-tricks comments */
/* FIRST LEVEL */
.nav > ul > li {
display: inline-block;
position: relative;
padding: 3px 10px 3px 0;
z-index: 100;
}
/* SECOND LEVEL */
.nav > ul > li > ul {
position: absolute;
left: 0;
top: 100%;
padding: 0 1000em; /* trick from css-tricks comments */
margin: 0 -1000em; /* trick from css-tricks comments */
z-index: 101;
visibility: hidden;
opacity: 0;
background: rgba(255, 240, 240, 0.8);
}
.nav > ul > li:hover > ul {
visibility: visible;
opacity: 1;
}
.nav > ul > li > ul > li {
padding: 3px 0;
}
If you wanted to get snazzy with the CSS, you could add this to the second level ul:
.nav > ul > li > ul {
...
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
If anyone is interested in making this work similarly in old IEs or wants deeper nested lists, let me know.
To give you a head start, here are some useful links that helped me:
Full browser width bars (CSS tricks article/comment)
Fixing z-index (helpful for IE7)
Chris Coyier really covers us at work lol.
You're quite right, in that that box model doesn't work that way.
There is one thing I can think of, and that is to set your divs to
position:absolute
and use the top, left, right attributes to position them. But, as you say, that won't work if you have position: relative on a parent element.
To be honest, it'll be difficult to achieve this without a horrible mess of workarounds which will probably break between browsers. I've seen peers and colleagues spend ages trying to implement things like this, building more and more precarious code 'fixes' to get it to work cross-browser, receiving complaints from clients about it not working in IE6 and Firefox 1.5, only to give up on that 'feature' entirely.

Resources