The CSS Jiggles

Another CSS problem for the forum, and this one kind of made me sick (literally) just watching my screen bounce all over the place!

The situation is this: I have a list of items that upon mouse over, I would like to have the list item be highlighted by adding some space (margin) between that li and the li above and below it, and then giving it some font weight: bold goodness, and maybe even a boost in font size. To achieve this, I am using the li:hover selector, and I’m getting good results.

The problem is this: everything below the li jiggles uncontrollably as you move the mouse up and down the list because it is being pushed or pulled by the new margin! Now, this isn’t so bad if it is just the list items below that are jiggling, that is understandable. What makes you cross eyed is any divs or paragraphs below the list that keep bouncing up and down.

At first, I thought I would just not be able to use this technique, but then I noticed that when you have two columns of lists that behave this way, the shorter column doesn’t jiggle anything below it, presumably because it has space to move. So then I thought, ok, I could add some kind of buffer element to absorb the jiggle, but all elements just push all the elements down.

I’m beginning to suspect I’m going to have to mess with the height of the container, problem is that the list is dynamic, so I don’t know what the height will be! Does anyone have the cure for my jiggles?

Here is some example code, first the CSS:

#wrapper {
	width: 600px; 
	margin: auto; 
	border: 1px solid #000; 
}

#col1 {
	widht: 300px; 
	float: left; 
}

#col2 {
	width: 300px; 
	float: right;
}

li:hover {
	font-weight: bold; 
	margin-top: 5px; 
	margin-bottom: 5px; 
}

.clearBoth {
	clear: both; 
}

#footer {
	text-align: center; 
}

Next the HTML:

<div id="wrapper">
	<div id="col1">
    	<ul>
        	<li>one jiggle</li>
            <li>two jiggle</li>
            <li>three jiggle</li>
            <li>four</li>
            <li>five jiggle...</li>
        </ul>
    </div>
    <div id="col2">
    	<ul>
        	<li>one</li>
            <li>two</li>
            <li>no jiggle!</li>
        </ul>
    </div>
    <div class="clearBoth"> </div>
	<div id="footer">
    	<p>I'm getting sick from all the jiggles!</p>
    </div>
</div>

Try it out, and you’ll see that poor bottom paragraph bouncing all over the place when you scroll over the first column, but not when you scroll over the second!

Someone help this guy! :slight_smile: I’ve poked at his code a bit, and I think I know what might be going on, but I’m not sure enough to try to explain it.

Thanks, Black Max. I think even a general discussion of what might be required may at least lead me down the right track. My possible solutions include adding height to the col div (but how to do this dynamically, I’m not sure of. I’d really like to not use JavaScript) or by using some sort of buffer element that compresses with the change in height of the elements above it. But if they’re are any other methods, I would really like to hear them!

You are right, the remedy would be to adjust the list height on hover to compensate the growing item margins (I suggest padding instead to avoid any flickering). E.g you can try to add the same length margins to the default list and then remove the list margins on hover.


ul {
    margin-top: 5px;
    margin-bottom: 5px;
[COLOR="Red"]    line-height: 1.2em;[/COLOR]
}

ul:hover {
[COLOR="Red"]    margin-top: 0;
    margin-bottom: 0;[/COLOR]
}
 
li:hover {
    font-weight: bold;
    padding-top: 5px;
    padding-bottom: 5px;
}

So close, but I’m still getting the jiggles. I like the thought though- use the container block-level element with its own hover to manipulate the document dynamically. The problem is that the ul hover exits and enters with the mouse going over the LIs- causing the flicker.

So maybe I’m going to have to use another pseudo selector to fix this, or maybe use a DIV instead of the UL- because you will never exit the container on mouse over…

More investigation required, but if anyone else has suggestions, please let me know!

I do not know if it is correct or not but it seemed to fix it for me on FF:

li {
    margin: 3px 0 3px 0;
    }

basically you were adding margin to the li when hovered… but not in its resting state…

hope it helps

Yeah, that would solve the problem, but this is not the intended effect I was going for. I don’t want all of the list items to be separated by the margin, I want the margin to appear on hover. So that it looks like the word has popped out of the list. The list is long enough that adding margin to the resting state would make the user have to scroll (most likely).

Whoops, seems I have an apology to make- the switch from margin to padding may have been the key to ease (not eliminate) the jiggling. (Sorry Erik) The following CSS:


li:hover {
	font-weight: bold; 
	font-size: 1.2em;
	padding-top: 5px; 
	padding-bottom: 5px; 
}

Does seem to ease the problem because on hover, the paragraph moves down, but as you move up and down the list the paragraph doesn’t jiggle like it did with the margin. It moves back into position when you exit the list.

Erik, when I tried setting the ul padding and then detect ul:hover - that caused the flickering because it would shift the padding from ul to li, so that distracted me from this solution. Thanks!

I think to make this effect look right you will need a little margin. Even if it is just 1px top and bottom. Also if you specify the font px in the normal and hover states you can make sure the thing does not move like this…

li {
    font-size: 15px;
	padding-top: 1px;
    padding-bottom: 1px;
	}
	
    li:hover {
	font-size: 17px;
    font-weight: bold;
    padding-top: 0px;
    padding-bottom: 0px;
    }

In this you are making sure that you have 17px in height in both states. 15 font height +2 padding vs 17 in font height… no joggles jiggles or other silly movement.

Ah beautiful!

What about the margin thing? This solution doesn’t provide any buffer between the list items, but for my purposes, the simple increase in font-size is good enough for me. Perhaps playing around with the amount of padding vs. font-size would tweak this perfectly.

Thanks!

Sorry I do not see a way to add margin to the hovered item but keeping the whole line in place. I wonder if there would be a way to handle this with jquery. Unfortunately I am just learning that stuff now so I cannot be of much help there. That being said I think it might be too much of a hassle to add a jquery to it for this little item. Good luck. If I think of any other possibilities I will post back. Good luck.