There are many answers given to the questions of the form "How should I suggest that ---- links be ----?" Most of them have some serious problems in current browsers or could in future browsers. Below I explain a way that both avoids problems in existing browsers and is forward-compatible. Unlike much of the theoretical advice I give, this is intended to be usable advice when the document is complete (it's not complete yet, though). Still, use it at your own risk.
The correct way to suggest styles for links is complicated
because of both browser bugs and differences between CSS1 and
CSS2. In CSS1, there were three link pseudo-classes, all of
which were mutually exclusive: :link
,
:visited
, and :active
. None of these
pseudo-classes applied to any elements other than links. CSS2
left :link
and :visited
as the link
pseudo-classes (and still mutually-exclusive), but it moved
:active
into the dynamic
pseudo-classes. CSS2 also added two new dynamic
pseudo-classes: :hover
and :focus
.
In CSS2, these dynamic-pseudo classes can match any element,
although in future versions of CSS, :active
and
:focus
may be restricted to matching elements that
take user input (as defined by a CSS property).
Before I show the correct way to write selectors that match link elements, I will show a number of common mistakes:
a
a:link
(when used to match all links):link
and :visited
pseudo-classes
are mutually exclusive, this does not match any visited links.a:link, a:visited
a
element (as opposed to
XML links).:link, :visited, :active
:active
selector
alone could match any element the user clicks on, rather than
only matching links.:hover
(to match hovered links)a:hover
is bad because it will match named anchors in
addition to links.):hover:link, :hover:visited
(to match hovered
links)a:active
or a:hover
(or variants)a:link
or a:visited
,
and therefore the order of the rules matters. This can be
confusing, especially since MSIE is buggy and treats (some of??) them as
if they had higher specificity.
The following are the best selectors to use for matching various
types of links. However, I do not advise grouping them. (By
that, I mean using a selector such as :link:active, :visited:active,
:link:hover, :visited:hover
.) Grouping could cause the
entire rule to be ignored if a browser supports one part of the
selector and not another, since browsers should ignore
the entire rule if they don't understand a part of the selector.
Furthermore, some browsers will allow only the color
property to differ between links, and I haven't carefully tested
suggesting that other properties are different for different types
of links.
:link
.:visited
. Rules that match only visited links should be placed after those that match unvisited links since some browsers (e.g., MacIE 4.5) incorrectly allow :link
to match visited links.:link, :visited
. Never add other simple selectors to this that might not be recognized by a CSS1 browser, since that would force a CSS1 browser to ignore the entire ruleset.:link:hover, :visited:hover
.:link:focus, :visited:focus
. Because of bugs in WinIE 5.0 (and other versions), put this rule before rules that would completely override it if it instead had a selector :link, :visited
(i.e., rules with that selector or separate rules for :link
and :visited
).:link:active, :visited:active
[1]. I recommend putting this rule after the rules to match hovered and focused links so that it will override them and a link that is both active and hovered will match the active link rule (which wins according to the CSS cascading order because it is later). This may be unnessecary in some browsers that incorrectly consider one state dominant.My demonstration document shows this method in use. (Because it suggests text-decoration, it does not show up correctly on Opera. See below.)
[1] This will not work on a pure CSS1 browser that supports :active
. However, I know of no such browsers. (One could match active links in such a browser with a:active
. Such a selector has the disadvantage that it could also match named anchors in CSS2 browsers.)
Here's how the following browsers will deal with the above
suggestion. Note that I haven't tested every possible
combination of things on every browser, so there may be bugs I
don't list below. If Eric Meyer's CSS
support mastergrid says that a browser doesn't support
:active
, the only thing I have tested is that my
demonstration file works correctly for visited and unvisited links.
a:active
to match active links.
However, all browsers that support a:active
will handle a
:link:active
rule correctly.:active
, :hover
, or :focus
text-decoration
or border
are suggested on
links. That is, if the text-decoration
property is given,
then the text-decorations get the correct color but the text does not.
However, if the border
property is given, then the border
gets the correct color (importantly, when the border-color is left at
its default), but the text-decorations and text do not. Suggesting
borders for links causes many other elements to have borders. Opera
also incorrectly allows :link
selectors to match visited
links for all (?) properties except color
.color
(others? I didn't try them
all...) given in a rule with selector :link
or
:visited
will match both visited and unvisited links.:link:hover
, etc., must be in that order, and why the
rules containing :link:focus
must come before rules that
override them when they are treated as :link
. Both
support :hover
and :active
only on links (so
that they are incorrectly "more important" in the cascade than
:link
and :visited
). (The definition of
:active
used is somewhat strange: links match
:active
when they have the keyboard focus (either because
they are being clicked or were just clicked or because the user got to
them by keyboard navigation). Netscape browsers define active links as
those on which the mouse is currently depressed.):link
to match visited links. Other than that, it behaves just like WinIE 4.0x
and 5.0.[2] The demo file has not been tested on this browser.
Note (2002-08-21): this document is now cited in an article by Bill Mason, which has some updated testing results.
(Back to CSS, David Baron)
LDB, dbaron@dbaron.org, 1999-09-05, 1999-10-24, 1999-11-07, 1999-11-17, 2000-01-11