14
votes

Safari and Chrome, as well as Opera and Firefox, can handle the :hover pseudo-class and adjacent-sibling selectors:

a:hover + div {}

This works.

However, when another adjacent-sibling is added:

div:hover + a + div {}

Webkit falls apart.

However, if you first hover over <a> and then hover over the <div> the style is applied as it ought to.

I'm further confounded, because if you add:

div:hover ~ div {}

with or without a style declared, it starts working as it ought to.

Demo

I see this problem in:

  • Google Chrome 15.0.874.121
  • Safari 5.1.1

for OS X.

Any ideas?

3
Yeah, this is a WebKit bug. I come across it occasionally. Elements apart from the :hovered one and its parents aren't updated. Nothing you can do about it, I'm afraid. - Ry-
Somebody observed completely opposite behavior here: stackoverflow.com/questions/5061509/… Definitely a WebKit bug either way, and one that apparently hasn't been completely fixed yet. - BoltClock
I found a more elegant solution to this on a more recent question, so I posted a similar answer here. - ScottS
Seems to apply also in to a :checked selector. - Jaakko Karhu

3 Answers

28
votes

you can overcome Webkit's pseudo classes + general/adjacent sibling selectors bugs by faking animation on the body element:

body { -webkit-animation: bugfix infinite 1s; }

@-webkit-keyframes bugfix { 
  from { padding: 0; } 
  to { padding: 0; } 
}

you can check it out here: http://jsfiddle.net/jalbertbowdenii/ds2yY/1/

13
votes

Easy Fix without Animations

Handled a similar issue here, where this idea of changed pseudo-classes solved it (note: nth-child(n) will always match):

div:hover + a:nth-child(n) + div
12
votes

Alternatively, the fix can be applied only to the elements that are having the update issue rather than to the body element:

http://jsfiddle.net/ds2yY/12/

.force-repaint { -webkit-animation: bugfix infinite 1s; }

@-webkit-keyframes bugfix {
    from { fill: 0; }
    to { fill: 0; }
}