Safari CSS :hover and Adjacent Sibling Selector Bug

Posted by Dan on Mar 17, 2008 @ 12:29 PM

I recently discovered a bug in Safari (Mac and PC) related to use the :hover pseudo class in conjunction with an adjacent sibling selector. The problem is that the mouseover event correctly changes the adjacent sibling's style, but when the mouseout event occurs the style is never reset. This means if you have the selector ul li:hover + li the adjacent selector's (+ li) style will be changed when the user hovers over the element, but the style is never reset once the user mouse's out of the element.

I've tested this CSS selector combination in IE7, IE8b1, FF2 (PC and Mac) and FF3b4 and in all those browsers when the mouse leaves the element being hovered, the style of the sibling element is reset to it's original state.

One problem with stating this as a "bug" is that I believe the CSS spec is unclear on what the correct behavior should be, but I do believe that the other browsers got this right. I definitely expect any visual changes applied to the screen on the :hover pseudo class to be undone when mouse leaves the target area.

It turns out I'm not the first to find problems with Safari's implementation of the :hover and adjacent sibling selector.

To see this bug in action, move your mouse pointer from the bottom of the list to the top. If you move from top to bottom you will not see the bug since the style is correctly reset once you mouse over the sibling element.

  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5
  • Item 6
  • Item 7

Here's what the CSS looks like behind the scenes:

<style type="text/css">
ul {
    margin: 0;
    padding: 5px 5px;
    list-style-type: none;
    width: 250px;
    height: auto;
    background-color: #e1e0e0;
    /* define font here for IE6 */
    font: 11px Arial, Helvetica, sans-serif;
}
ul li {
    cursor: pointer;
    white-space: nowrap;
    color: #666;
    border-top: 1px solid #fff;
    padding: 2px 20px 2px 6px;
    margin: 0 10px;
}
ul >
li.end {
    border-bottom: 1px solid #fff;
}
ul > li:hover {
    border-top: 1px solid #999;
    background-color: #999;
    color: #fff;
}
ul > li:hover.end {
    border-bottom: 1px solid #999;
}
ul > li:hover + li {
    border-top: 1px solid #999;
}
</style>

Odds are high that you might never run into this bug, but I'm working on a menu system that requires a pretty complex CSS rule set and this bug is causing me serious problems in Safari. I may end up needing to implement a JS in order to resolve the problem.

Categories: HTML/ColdFusion

9 Comments

  • Since Apple just released v3.1, I decided to re-test the case. It's still having the problem. Actually, it looks like things are more broken now. When moving down the list the adjacent sibling's border no longer changes to dark grey on hover (it's white) but does change once you hover out. Very weird...
  • You can always file bugs at http://bugs.webkit.org
  • I'd like to add that I've noted this one as well, I'm using a DL/DT/DD combination for a nav with flyout "tooltips", displayed via dt:hover + dd - and sometimes they get "stuck", the first item will display correctly but then doesn't go away etc.

    I've also noticed that with a left-to-right UL/LI-based nav, it seems like moving the mouse left to right causes the drop-downs to appear, but going right to left doesn't work.

    From what I've seen, both of the above have been consistent with Safari 2 and 3.
  • @Oliver:

    I filled a bug with Apple, but saw the bug was already filed with Webkit (as Greg pointed out.)

    As more browsers start better support CSS, I think we'll see more people using the pseudo selectors in their code--since it does simplify your code immensely.
  • That bug still exists, its a shame.
    The sibling selector in conjunction with :hover simplifies styling of ajax star rating widgets a lot.
    Its unbelievable that I managed to make something work fine in both IE & FF with the first try, and it doesn't work with webkit! LOL!
  • Not really, webkit is full of bugs, people just get distracted by the shiny Apple logo.

    There are also instances where
    ul.somecontainer li:hover ul.dropdown{display:block;}

    would trigger on all li elements in ul.somecontainer even if they didn't have a ul.dropdown child

    and clear:left still doesn't work properly.
  • I ran into this bug working on a CSS-intensive project, and here is a way to fix it with CSS
    http://css-tricks.com/8439-webkit-sibling-bug/

    However, the bug is already fixed in recent versions of Chrome and Safari.
  • @Ryan:

    Nice to know there's a CSS only fix.

Comments for this entry have been disabled.