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.
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);
});
Always great to know more stuff! I did something like this a while back as well, but didn’t use the same kind of selectors; Display Social Media Icons beautifully using CSS3. Thanks Chris, for showing another kind of solution for this problem!
Whoops – my apolagies! Your demo goes even one level deeper, instead of the “basic” form. Even better!
Given me the greatest IDEA!!
Love this, thanks.
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.
“Doesn’t render well” kind of vague isn’t it? :p
this is kind of obvious.. but i love that you’ve done on the demo page :-)
Awesome demo!
And am I the only one having problems seeing things (menu text and text in other areas) on css-tricks?
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.
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?
I do this on my site. Similar syntax
it’s a neat effect. doesn’t work in older versions of IE, but I can live with that
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.
I appreciate that you provide the code and a demo. Thanks!
This is nice post. It’s really useful. Thanks for shearing your ideas!
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.
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?
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.
Genius! I’ll definitely be implementing this in my site. Thanks!
very neat post!
Nice post! I can always learn something from you, thanks!
Nice!! I’m going to use this straight away!!
You might have some mystic force – I just looked for that, thanks Chris!
Thanks a lot! This is clean and easy!!
This is a wonderful idea!!
Awesome demo! Simple tricks. I give it a try..
usefull tutorial for me, thanks
The Demo is cool, love it. Can’t wait to see how this hovering thing work. Thanks
Thanks for another addition to my CSS arsenal.
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.
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>
Maybe look at the concept behind remote linking: https://css-tricks.com/remote-linking/
Or… JavaScript!
Thanks Chris, I’ll check it out. Was trying to avoid javascript if I could, css would be more elegant and painless.
Cheers!
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>.
I love this! This is the kind of tut that makes me want to go back and redesign about 1000 things.
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
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
* hover-on-everything-if
Nice and useful article. Thanks
nice tutorial, but have you tested your site in chrome?
Take a look at the css3-pseudo class “:not()”
http://www.w3.org/TR/css3-selectors/#negation
Good Job.
:hover pseudo has issues with older versions of IE.
IE sucks!
Excellent. Really focuses the user on the target area – will certainly be using that in my next website project. Thanks.
Nope! IE is a big effect on these kind of approaches.
i can use it on image gallery… coool… :)
great post
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;
}
We just implemented this on New Hiker and used some of your code. (The Social Media icons in the left column)
Thanks for the tip!
Looks good, thanks for sharing.
This helped me alot, thanks alot mate :)
Great article. If images we can greyscale the other images.