Grow your CSS skills. Land your dream job.

Avoid “CSS Jitter”

Published by Chris Coyier

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.

Comments

  1. Permalink to comment#

    I actually laughed out loud when I saw Jitter Man doing his thang!

    I suppose this could work to your advantage, like you mention it does produce a cool effect when controlled.

    Chris

  2. Permalink to comment#

    loved your jitter man ! :p

  3. Sweet! I’m glad somebody enjoyed it =). I posted it just cringing thinking people would think it’s so dumb.

  4. Oh jitter man thinks he can fly flapping his arms like that…

    Great post.

  5. Jayzon
    Permalink to comment#

    lol

    Jitter Man is great! ;-)

    This hover-jumping is really annoying. When I started out with CSS, there was this problem, whenever I changed the border of block elements on hover. I don’t know if it’s the best way to do so, but now, I simply add a border to the block element itself matching the background-color & changing the border-color on hover then does the job perfect, no jumping anymore.

    Greetings

  6. ydx
    Permalink to comment#

    LOL@Jitter man dance. That’s good stuff.
    I think the reason Jitter Man dances is because the image dimensions and the div dimensions are not the same size.

  7. Mario
    Permalink to comment#

    good tip, thanks!

  8. Reading this late due to holidays but a good laugh on a Monday morning :lol:

    In regards to saying you could use it effectively for a hover state by making it “jitter” a pixel or two, I would disagree as it would cause problems with people who have elpelyte and also could cause the whole page to move/ jitter which would cause disruption for the viewer..

  9. Permalink to comment#

    The trick here is to use a technique such as sprite backgrounds (http://www.alistapart.com/articles/sprites).

    Sorry, ydx, but the jitter problem is not caused by image dimensions and division dimensions being different.

    Krumpet

  10. Permalink to comment#

    Oops, actually, I should have submitted this link:

    http://wellstyled.com/css-nopreload-rollovers.html

    That is actually where the idea came from. A List Apart just expanded on it.

    Krumpet

  11. We’ve posted about CSS Sprites here as well.

  12. LOL…great article.

  13. Permalink to comment#

    This is awesome. Is that the official name or just one that you folks use? This has bugged me for a while though I never knew what to call it or why it happened. thanks!

  14. Peter K.
    Permalink to comment#

    I would have actually liked some info HOW to avoid items jumping around (e.g. when the active element displays a dotted frame). It's absolutley clear that I should avoid it, I don't need to be told. But the question is HOW?

  15. Greetings,

    Thank you for all your good advices on CSS manipulation.
    Is this problem still an issue ? The article is dated from 2007.

    I am encountering problems with random content jittering when scaling a CSS circle with an hover effect (transition, transform).
    Is there any solution to this type of problem ?

    Thanks,

  16. I found this article while searching for a solution to this problem; since this article didn’t offer a solution, I had to keep looking. The issue I faced was jitter due to adding a border on hover. The solution I found was to simply add the style intended for the hover state to the element’s inherent state, but in a way that is not visible. For example, having a default border-bottom:1px solid transparent; then border-bottom:1px solid red; on the hover state.

    I would assume that similar approaches could be used for the other jitter-inducing problems.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".