Can anyone tell me if there\'s any reason to use a {}
instead of (or adjacent to) a:link, a:visited {}
in my stylesheet? I\'ve had inconsistent re
There are two cases where an a
may not have an href
property. The first is regular anchors (i.e. <a name="someplace" />
) and the second is pure Javascript interaction (i.e. <a onclick="doSomething( );" />
). Those are not 'links' and shouldn't be styled the same.
EDIT: To clarify, a:link
is pretty much equivalent to a[href]
(I believe the former notation existed before the attribute selectors were available or standardized). So a reason to use a
instead of a:link
would be if you wanted all anchor tags styled the same. The default styles in some browsers display the two differently - such as underlines only applied to a:link
and not to a
.
Well you could have an anchor that is just an anchor. For example,
<a href="#top">Return to top</a>
<a name="top">Top</a>
Which corrects your false assumption (albeit, an anchor isn't needed for the "top", but it's the most philosophically correct).
In addition, as Sarfraz said, a {}
overrides all occurrences of other a:
style properties if styled (and assuming the a {}
is after the other a:
declarations).
This is of course assuming there would never be a reason to use an
<a>
tag without anhref
value. Maybe that's a mistaken assumption.
Well, actually... not every <a>
element needs to have a href
attribute. Indeed, it's still not required in HTML5 to specify href
for every <a>
. Chris Blake and Ryan P talk about the concept of named anchors, and I'll add that while the name
attribute for <a>
has been made obsolete as of HTML5, named anchors are still rife and will continue to be, simply by legacy and tradition.
That said, going forward, authors are recommended to use id
attributes and not named anchors to designate document anchor fragments.
Also, <a>
elements that lack href
attributes but have onclick
attributes for JavaScript are a mess. Even if you insist on using onclick
to bind events, for the sake of graceful degradation you should at least point it somewhere using href
.
But to make things simple, let's assume that you won't be writing <a>
elements without href
attributes.
With this in mind, going back to the CSS selectors, there are two important points to consider:
No, the selectors a
and a:link, a:visited
are not strictly equivalent. I'll quote a previous answer of mine on this topic:
The selector
a
should match any<a>
elements, whilea:link
only matches<a>
elements that are unvisited hyperlinks (the HTML 4 document type defines hyperlinks as<a>
elements with ahref
attribute). Nowhere does it state in either specification thata
should automatically translate toa:link
or vice versa.
In other words, in HTML, a:link, a:visited
(in CSS1) is strictly equivalent to a[href]
(in CSS2 with an attribute selector), rather than a
. Note that it doesn't matter whether the attribute has a value or not, as long as it is present, hence [href]
. Note also that this is true for all current standards of HTML, and I believe this includes HTML5, since as mentioned above href
is not a required attribute in any existing spec.
Just bear in mind, that other languages may define completely different semantics for :link
and :visited
— it just so happens that they coincide with an equally specific selector in HTML, which is covered next...
This is a huge gotcha: a
is less specific than either a:link
or a:visited
, which is a very common source of specificity problems that are particularly evident when applying styles to a
, a:link
and a:visited
separately. This then leads to all kinds of !important
hacks to get around a lack of understanding of specificity.1
Fortunately, an attribute selector is as specific as a pseudo-class. This means you can use a[href]
to mean both/either a:link
and/or a:visited
, and not run into specificity issues because they are equally specific!
For example, consider this CSS:
/* All unvisited links should be red */
a:link {
color: red;
}
/* All visited links should be slightly darker */
a:visited {
color: maroon;
}
/* But no matter what, header links must be white at all times! */
body > header > a {
color: white;
}
This doesn't work as expected, because a:link
and a:visited
are more specific than body > header > a
, so header links will in fact never be white:
/* 1 pseudo-class, 1 type -> specificity = (0, 1, 1) */
a:link, a:visited
/* 3 types -> specificity = (0, 0, 3) */
body > header > a
Now the first thing that comes to mind for most CSS coders is to throw in !important
, trumping specificity altogether:
body > header > a {
color: white !important;
}
But this gets you all kinds of bad rep, right?
Well if you feel uncomfortable using !important
, you can either use a[href]
, as discussed above:
/* 1 attribute, 3 types -> specificity = (0, 1, 3) */
body > header > a[href] {
color: white;
}
Or do this, which has the problem of being verbose but is friendlier to older browsers as well as simply being more intuitive:
/* 1 pseudo-class, 3 types -> specificity = (0, 1, 3) */
body > header > a:link, body > header > a:visited {
color: white;
}
In the end, this is all still mad subjective, but I follow these personal rules of thumb:
Apply to a
styles that do not depend on the state of a link (i.e. as long as it's a link will do).
Apply to a:link
and a:visited
styles where it does matter whether a link is visited or not.
Taking into account the specificity problems mentioned above, do not mix any declarations between both a
and a:link
/a:visited
rules. If I need to apply the same property to both states somewhere, but I already have it in separate a:link
and a:visited
rules, write a selector that combines both pseudo-classes; don't just use a
!
For example, here are the link styles I use in my site:
a {
text-decoration: none;
transition: text-shadow 0.1s linear;
}
a:link {
color: rgb(119, 255, 221);
}
a:visited {
color: rgb(68, 204, 170);
}
a:hover, a:active {
text-shadow: 0 0 0.5em currentColor;
outline: 0;
}
/* ... */
footer a:link, footer a:visited {
color: rgb(71, 173, 153);
}
The text-shadow
transition is defined for all a
elements, regardless of whether they are visited or not, because the transition only takes effect when one of them is moused over and clicked (corresponding to the a:hover, a:active
rule).
Now, I want visited links to have a slightly darker shade than unvisited links, so I put the colors in separate a:link
and a:visited
rules. However, for some reason, I want footer links to appear the same color whether they're visited or not.
If I use footer a
, I'll run into the specificity problems described above, so I choose footer a:link, footer a:visited
instead. I could easily go with footer a[href]
because that works just as well, but I personally prefer specifying both pseudo-classes because it's more intuitive, even if it makes the selector a little longer.
1 Specificity and repeated selectors have posed such a huge problem, in fact, that the working group has put up a proposal for an :any-link pseudo-class in the next spec to do away with having to rely on the href
attribute in HTML, but that will have to wait a long time before seeing the light of day (and who knows what it'll be called by then):
/* 1 pseudo-class, 3 types -> specificity = (0, 1, 3) */
body > header > a:any-link {
color: white;
}
The a:link
and a:visited
are used to specify custom (other than browser default) colors for normal and visited links respectively whereas a {}
is used to overwrite all styles including a:link
, a:visited
, a:active
. For example following will have same color irrespective of whether link is active, visited or not or hovered upon:
a { color:red; }
You can avoid that by using individual styles eg a:pseudoClass
notation.
a:link
and a:visited
have specific meanings. a
by itself will affect all <a>
elements whereas a:link
will only affect links that have not yet been visited and a:visited
will only affect links that have been visited.