Hover on “Everything But”

Published by Chris Coyier

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.

Update August 2012: Michelle Eaton writes in with this JavaScript to do the job, if you must:

$("#all ul li").hover(function() { // Mouse over
  $(this).siblings().stop().fadeTo(300, 0.6);
  $(this).parent().siblings().stop().fadeTo(300, 0.3); 
}, function() { // Mouse out
  $(this).siblings().stop().fadeTo(300, 1);
  $(this).parent().siblings().stop().fadeTo(300, 1);
});