Safari CSS :hover and Adjacent Sibling Selector Bug

Categories: HTML/ColdFusion

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.

Comments

Dan G. Switzer, II's Gravatar 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...
Oliver's Gravatar You can always file bugs at http://bugs.webkit.org
Scott Schiller's Gravatar 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.
Dan G. Switzer, II's Gravatar @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.

Add Comment



If you subscribe, any new posts to this thread will be sent to your email address.