Avoid “CSS Jitter”

Avatar of Chris Coyier
Chris Coyier on (Updated on )

With more power, comes more responsibility.

One of the things that CSS allows you to control is the hover state of many objects, most notably, anchor (<a>) elements. Typically, the hover state is styled with color changes, or perhaps something a bit fancier like a background-image change (or a background-position change re: CSS Sprites).

But that’s not all you can change. Just as easily, you are able to change font-weight, margin, padding, or literally height and width if you are dealing with a block-level element. Changing any of these things on hover is entering dangerous territory.

Why dangerous? Because you are changing the clickable region of the element. If the new clickable region is positioned such that the cursor falls outside of it, the hover event will trigger off and revert to it’s default styling, which will change the clickable region again, which will cause your cursor to be inside of it again, which will change the styling again, which will….. You get it, “CSS Jitter”.

“CSS Jitter” can happen any time you change the size of an object on hover.

It’s as simple as that. If you want to avoid CSS Jitter, don’t style the hover states of objects to change size in any way.

There are some examples where changing the size is safe. Basically if the clickable area becomes bigger on rollover in all directions. For example, bolding text on rollover. Since the boldness will cause the object to become bigger in all directions, you will never trigger a jitter. However if you did the opposite, unbolded text on rollover, the clickable area would become smaller and almost certainly trigger jitter.

Here are some hover styles that could trigger “CSS Jitter”

  • Bolding/Unbolding text
  • Changing Margin or Padding
  • Changing Border Size
  • Chaging Width or Height
  • Changing Line-Height

Check out CSS Jitter-Man.

OK, this is really stupid, but just to illustrate exactly what I am talking about, I created CSS Jitter-Man. Jitter-Man is an anchor element which is 246px wide at default, but upon rollover, he shrinks to 212px wide. So, if you mouse onto Jitter-Man from either the right or the left, he will shrink. This causes that clickable area to shrink which puts your mouse outside of it and he will grow again..and thus the jitter. Check out the example:

css-jitter-man-example.png

This really isn’t a huge epidemic or anything, it’s just something to be aware of. It is likely to show up in much more subtle ways, which is actually where I first got this idea. I had used a border-bottom from my anchor elements, so I could give a little padding to the bottom before the underline. Then on rollover I reduced that padding by a single pixel so the underline seemed to jump up a little bit, which was a nice effect. But what that caused is a single pixel region where CSS Jitter would occur. Not good. Ultimately I chose another method for the rollover.