Issues Arising From Arbitrary-Element hover

 

Summary: Thanks to long-standing limitations, we're used to thinking of hover styles as applying only to hyperlinks, which has led to some sloppy authoring practices that are now causing problems for some Web sites. This technote explains the source of the problems and how to avoid encountering them. Many authors make use of the CSS2 pseudo-class :hover to style their links. This innovation, first introduced by Microsoft® Internet Explorer and later adopted into the CSS specification, is very popular for the styling of text links, particularly those that are supposed to look and act like JavaScript-driven "rollovers." However, advancing CSS support in browsers has caused some unexpectedly aggressive hovering behavior on some pages.

Section 5.11.3 of CSS2 defines the three dynamic pseudo-classes (:hover, :active, and :focus) and then goes on to say:

CSS doesn't define which elements may be in the above states, or how the states are entered and left. Scripting may change whether elements react to user events or not, and different devices and UAs may have different ways of pointing to, or activating elements.

Thus, although authors are used to thinking of these states as applying exclusively to hyperlinks, they are not so restricted by CSS2. Any element can, in theory, be in any of the three states, and thus can be styled based on those states. This has not traditionally been the case.

Bare Pseudo-Classes

The second piece of the problem comes when we consider the effects of a "bare" pseudo-class in a selector. For example:

:hover {color: red;}

This is equivalent to the CSS2 rule:

*:hover {color: red;}

..which translates as "any element that is being hovered should have its foreground colored red." Thus, hovering over paragraphs, tables, headings, and any other element in a document will cause text to become red.

A common variant is to use a bare class and hover pseudo-class together, like this:

.nav:hover {color: red;}

In situations where the only instances of the class value nav are applied to hyperlinks, this will work fine. However, rules of this type are usually seen in conjunction with markup like this:

<td class="nav">
<a href="one.html" class="nav">one</a> | 
<a href="two.html" class="nav">two</a> | 
<a href="thr.html" class="nav">three</a> | 
<a href="fou.html" class="nav">four</a>
</td>

Because the enclosing table cell has a class of nav, the vertical-bar characters will turn red when the user moves the mouse pointer anywhere within the table cell. The links will also turn red when they are hovered.

Gecko Behavior

In browsers based on Netscape Gecko builds later than 20020410 (Netscape 6.1+), :hover styles can be applied to any element in a document. Thus authors who have used bare pseudo-classes, or bare class-pseudo-class combinations, are at risk of seeing hover styles applied to more than just their links. The most reliable fix is to add the anchor element to the selectors, like this:

a:hover {color: red;}
a.nav:hover {color: red;}

In an attempt to avoid causing problems for legacy documents, browsers based on Mozilla 1.0 and later (Netscape 7+) include code that causes bare pseudo-classes to be restricted only to links if the document is rendered in "quirks" mode. In browsers based on the engine found in Mozilla 1.3b and later, this quirk is extended to cover selectors that combine a bare class selector with the :hover pseudo-class (see bug 169078 for details).

Named Anchor Problems

In addition to the effects described previously, there are two other relatively common effects that authors may not expect. One is easily fixed by validation, but the other is a little more subtle.

First, there is the problem of authors who open a named anchor but do not close it. For example:

<a name="pagetop">
<h2>My Page</h2>

Without a </a>, this name will effectively enclose the rest of the document. This generally means that the rest of the document will take hover styles. Consider the effects of the following rule:

a:hover {color: red;}

In a document with an unclosed named anchor, any text that follows the anchor's open tag will be colored red (unless another CSS rule intervenes).

This brings up the second common problem, which is that named anchors can accept hover styles. Although authors may intend the selector a:hover to apply only to hyperlinks, it will also apply to named anchors, since the selector merely states that any a element which is in a hover state will be styled. In order to avoid this problem, authors should use the combined pseudo-class syntax described by CSS2:

a:link:hover {color: red;}
a:visited:hover {color: maroon;}

Note that, with this syntax, it is possible to style visited and unvisited links differently when they are hovered. This was not possible with simple a:hover. It does mean, of course, that the selector a:link:hover will only apply to unvisited links, so authors who want the same hover style to apply to both visited and unvisited links should group the two selectors into a single rule.

Recommendation

To avoid unexpected problems, authors are strongly encouraged to include element names in dynamic-state pseudo-classes that are meant to be applied to hyperlinks. Furthermore, combining pseudo-classes prevents hover styles from being applied to non-hyperlink anchors. Thus, a:hover should always be used instead of just :hover, and a:link:hover (and a:visited:hover) are preferred to the simpler a:hover

Original Document Information

  • Author(s): Eric A. Meyer, Netscape Communications
  • Last Updated Date: Published 07 Mar 2003; Revised 21 Mar 2003
  • Copyright Information: Copyright © 2001-2003 Netscape. All rights reserved.
  • Note: This reprinted article was originally part of the DevEdge site.

Document Tags and Contributors

Tags:
Last updated by: teoli,