Hover on “Everything But”

Mar 23 2011
55

Adding a hover state to an element is durn easy. Let's use an opacity change as an example:

div {
   opacity: 1.0;
}
div:hover {
   opacity: 0.5;
}

But what if we want to have that hover state apply to everything but the element actually being hovered over? (e.g. other adjacent sibling divs)

Let's assume this basic HTML:

<section class="parent">
  <div></div>
  <div></div>
  <div></div>
</section>

We'll apply the current CSS properties to all the children of the parent when the parent is in the hover state.

.parent:hover > div {
  opacity: 0.5;
}

Then when the parent is hovered and the individual div is hovered, we bump the opacity back up, giving the final effect we are looking for.

.parent:hover > div:hover {
  opacity: 1.0;
}

Real World?

A similar kind of thing is in the Twitter for Mac app on individual tweets:

Demo

This idea can be extended into multiple levels of depth. Here is an example of three "lists." All list items have full opacity in their regular state, but as you roll over the lists, the currently hovered list is slightly more opaque than then others, and the currently hovered list item is fully opaque.

View Demo   Download Files

And yes, old you-know-who browsers don't do :hover on anything but anchor links. If it's mission critical, use JavaScript to detect mouseenter events on them and apply/remove class names.

Subscribe to The Thread

  1. Love this, thanks.

  2. Enrique Moreno Tent

    Chris, do you know that your website doesnt render well? At leas in my conditions (Chromium under Ubuntu Linux). I don’t know if this is also true of other OS. Please check it out, because it has gone on for long time and it’s driving me crazy.

  3. this is kind of obvious.. but i love that you’ve done on the demo page :-)

  4. felipe

    Awesome demo!
    And am I the only one having problems seeing things (menu text and text in other areas) on css-tricks?

    • Enrique Moreno Tent

      No. I have the same issues.

    • what browser/OS are you using? I’ve never run into problems with visibility

    • Its Chrome problem. After updating mine to version 11, it seems fine now.

    • Gary

      I’m running Chrome 11 and the “syntax” boxes are almost unreadable, and text on the buttons in some places are not showing up.

    • Similar problems. Maybe Chris is making some tweaks?

  5. I do this on my site. Similar syntax

    <style>
       ul:hover li{ color: gray; }
       ul:hover li:hover{ color: navy; }
    <style>
    <ul>
       <li>item</li>
       <li>item</li>
       <li>item</li>
    </ul>

    it’s a neat effect. doesn’t work in older versions of IE, but I can live with that

  6. Eric

    Google Page Speed declares that this is a “potentially inefficient use of :hover” which has been known to cause issues with other hovering effects on some pages. most notably IE versions, but ive seen this bleed through and cause performance issues with hovering in FF as well.

    Be warned.

  7. I appreciate that you provide the code and a demo. Thanks!

  8. This is nice post. It’s really useful. Thanks for shearing your ideas!

  9. very cool, I am doing that plus a little more css transitions on the nav on my current site. I will say that using css to handle things that you would normally use an image for will help your load time greatly.

  10. but, is there some reason to put the “:hover” on every selectors? I mean, is not enough to put it just in the las one you are interested on being hovered?

    • bezoeker

      It actually is, I did a quick test with Web Developer toolbar and reduced that part to:

      #all:hover a {
      opacity: 0.2;
      }
      #all ul:hover a {
      opacity: 0.5;
      }
      #all ul a:hover {
      opacity: 1;
      }

      Only tried it in Firefox though, maybe it’s a fix for other browsers

    • it’s because, in this example, we want a group of items we’re not hovering on to change, while the one we’re actually hovering on stays the same.

      To do this, we need to change all of the items in the group (i.e., #.parent:hover ), and then change the one item we’re actually hovering on ( .parent:hover > .item:hover ) back to its original value.

    • nevermind; I see what you mean.

      It does appear to work in modern browsers (I tried in Fx3.6, Opera11, and Chrome10).

      When I was implementing this on my own site (it was a couple years ago), I remember I was forced to use the extra :hover selectors – I don’t remember which browsers required them, however.

  11. Genius! I’ll definitely be implementing this in my site. Thanks!

  12. very neat post!

  13. Nice post! I can always learn something from you, thanks!

  14. Nice!! I’m going to use this straight away!!

  15. You might have some mystic force – I just looked for that, thanks Chris!

  16. Thanks a lot! This is clean and easy!!

    This is a wonderful idea!!

  17. Awesome demo! Simple tricks. I give it a try..

  18. usefull tutorial for me, thanks

  19. The Demo is cool, love it. Can’t wait to see how this hovering thing work. Thanks

  20. Debbie

    Thanks for another addition to my CSS arsenal.

  21. Older Version of Browsern do not understand the :hover for div, li, etc. For this Browsers you can write a little bit of javascript to show the hover effect.

    • I too agree with your point. This is cool. but seeing current implementations by the browsers, I would still prefer java script based approach to achieve similar effect.

      http://www.technobits.net – Latest buzz, tips and tricks in Software Development.

  22. Perhaps someone can help. My site is like a shopping mall map (like going to a physical mall and looking at the directory) and I would like to change the opacity of a group of stores (class) based on hovering on the legend entry of the same class. Because you can search and filter the stores in various ways, the structure and order of the stores is fluid but I use class to color code the background images.

    The basic structure is below. I can have the legend as another div inside the mall if that helps but the question is:

    Can I hover over class ‘shoes’ in the legend and highlight ‘store_1′ and ‘store_4′ (and any other shoe stores) based on their class?

    (BTW, if you can do that I highly recommend writing up a separate blog entry – I’m sure lots of people would be interested.)


    <div id="mall_stores">
    <div id="store_1" class="shoes">...</div>
    <div id="store_2" class="electronics">...</div>
    <div id="store_3" class="books">...</div>
    <div id="store_4" class="shoes">...</div>
    ...
    </div>
    <div id="legend">
    <div id="class_1" class="shoes">shoes</div>
    <div id="class_2" class="electronics">electronics</div>
    <div id="class_3" class="books">books</div>
    </div>

  23. Robert

    Hi;
    OK, I’m still way back at the starting line for CSS so I’ve still got lots of questions.
    One of which is what is the “>” used for in the code like here (from above)
    .parent:hover > div { opacity: 0.5;} ?

    • The “>” is the child selector. So in the example you use it will select only those div tags that are children of something with the class “parent” that is being hovered on.

      It differs from the usual “ancestor descendant” selector in that it only selects direct children, not descendants further down the tree.

      So a selector like “div a” will select all tags within a but “div > a” will not select an that is within a within a .

    • Ah, HTML is interpreted. So my last paragraph should be:

      So a selector like “div a” will select all <a> tags within a <div&tg; but “div > a” will not select an <a> that is within a <p> within a <div>.

  24. I love this! This is the kind of tut that makes me want to go back and redesign about 1000 things.

  25. Aman

    Wow this looks really cool, I see lot of potential for this. But this doesn’t seem to work with Internet Explorer!

    • Have noticed also not with Netscape

  26. hey Chris,

    as $(‘every #day > .hour: first’).educateMe(‘http://feeds2.feedburner.com/CssTricks’)

    Let me not use words like amazing, love or aaaaaawsaaaam* :hover{ so much energy, so much enthusiasm, so unbelievable MUCH time for needed real social work (->sharing) – that it is (if I think back, when I started learning, trying  constantly landed on your site after goo’ling smth…) ! }

    This technique is found in almost all my sheets. Would love to see more of this kind of tricks -> published at this “prominent/celebrated” site – that it is! BECAUSE FireFoxyBaby – that it WAS – does not please anymore. So if you got anymore of those “simple” tricks for which I use usually
    if(!$.browser.mozilla) JS
    else THANKS!

    .a.hover strong: { border:1px solid black; }
    .a:hover strong.no_border { border:0; }
    .a:hover > strong:first-child:hover { border:1px solid blue; }
    c:hover .a:hover > strong:first-child:hover { border:1px solid red; }

    You are a sweet one! That’s why people come back: You didn’t make a tut out of it. :)

    Would love to work one day with you… “own” site is down right now (but you see the email.address ) – could be nice, would be really nice.

    Usually don’t do comments – first timer, almost(that it is) -> was tired of empty phrases.

    *smash_mag

  27. * hover-on-everything-if

  28. Nice and useful article. Thanks

  29. nice tutorial, but have you tested your site in chrome?

  30. Take a look at the css3-pseudo class “:not()”
    http://www.w3.org/TR/css3-selectors/#negation

  31. Good Job.
    :hover pseudo has issues with older versions of IE.
    IE sucks!

  32. Excellent. Really focuses the user on the target area – will certainly be using that in my next website project. Thanks.

  33. Nope! IE is a big effect on these kind of approaches.

  34. manoj

    i can use it on image gallery… coool… :)

  35. josephhyunkim

    great post

  36. You can do this faster with :not

    div:not(:hover){opacity:0.5}

    Or using your demo:

    #all:hover a:not(:hover) {
    opacity: 0.5;
    }

    Instead of:

    #all:hover ul:hover a {
    opacity: 0.5;
    }
    #all:hover ul:hover a:hover {
    opacity: 1;
    }

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