What's the :any-link pseudo-class for?
:any-link
is a new pseudo-class proposed in Selectors level 4, that matches all elements that would be matched by :link, :visited
. From what I see, its main purpose is to simplify selectors that need to select any hyperlinks, since the naming of :link
is misleading; it specifically means unvisited links only, rather than all hyperlinks (which makes it essentially the opposite of :visited
).
For the purposes of :link
and :visited
, WHATWG HTML and W3C HTML5 both define a "hyperlink" as any one of:
An
<a>
element that has anhref
attribute. This excludes named anchors (that is,<a>
elements without anhref
attribute but instead with aname
attribute), which were used traditionally to mark anchors in a page, now superseded by the use of anid
attribute on any element. See named anchors in HTML 4.An
<area>
element that has anhref
attribute.A
<link>
element that has anhref
attribute.
For example, consider a scenario where links in the page header should be colored differently from all other links:
body > header > a:link, body > header > a:visited {
color: white;
}
Notice the body > header
part is duplicated across both selectors. This seems redundant, but is currently necessary in order to color links in the page header differently from the rest, but regardless of their visited state. This is because body > header > a
is not specific enough which requires using !important
to override anyway, and body > header > a:link
troublesomely only applies to unvisited links.
With the :any-link
pseudo-class, you can simply do this instead:
body > header > a:any-link {
color: white;
}
Specificity is exactly the same as with each individual half, so there should be no issues there.
Of course, since no browser implements it unprefixed yet, that won't work. As an alternative, considering you're most likely working with an HTML document anyway you can just use a[href]
instead, which works in all browsers including IE7+ on top of also being equally specific:
body > header > a[href] {
color: white;
}
There's a much more elaborate explanation regarding the use of a
versus a:link, a:visited
versus a:any-link
versus a[href]
in this other answer of mine.
Like anything else that has a prefix in CSS, :-moz-any-link
and :-webkit-any-link
exist only for experimental purposes, so you shouldn't use them with your sites. Besides, even if you were to use them right now, you'd have to duplicate the rules themselves (and not just the selectors!) since browsers have to drop entire rules on unrecognized selectors, rendering them pretty useless in real-world code!
As of early 2013, no other implementations of :any-link
exist that I know of. I'm unsure as well as to whether this was implemented by the respective vendors and then proposed for inclusion in Selectors 4, or if it was preliminarily specced before the vendors began implementing it, but I don't think that matters.
Speaking of which, be sure not to confuse the :-moz-any-link
/:-webkit-any-link
pseudo-class with :-moz-any()
/:-webkit-any()
, the latter of which is specced as :matches()
instead (possibly to avoid naming confusion?).
What's the point of the :link pseudo-class?
The a:link
selector lets you set the styles on <a>
tags that actually link somewhere.
Bare <a>
tags without an href
attribute are traditionally used as markers in a document; setting the location to document.html#foo
will jump you to wherever <a id="foo">
is in the document. It is, after all, called an "anchor" tag for a reason.
Traditional HTML may look something like this:
<h2>Navigation</h2>
<a href="#ch1">Chapter 1</a>
...
<h3><a id="ch1">Chapter 1</a></h3>
<p>It was the best of times...</p>
Subsequent HTML standards let you use the document.html#thing
syntax to jump to any element with the attribute id="thing"
, but it wasn't always the case.
CSS pseudo class :link not supported. Is there any equivalent?
Theoretically, in selectors-4 you can write :any-link:not(:visited)
, but you are going to be hard-pressed to find any browsers that support :visited
but not :link
, let alone :any-link
, browser regressions notwithstanding.
A slightly more widely-supported selector requires knowledge of the document language since the link pseudo-classes themselves match different elements based on document semantics. In HTML, :link
can be expressed as the following level 3 selector-list:
a[href]:not(:visited), area[href]:not(:visited), link[href]:not(:visited)
The same caveat applies.
If you're asking about browsers that support neither of the link pseudo-classes, remove the :not(:visited)
from the above selector-list. If you're asking how to match links based on their visitedness in browsers that support neither pseudo-class, then it becomes impossible. But there are no known browsers that lack support for the link pseudo-classes, so this will never be a problem if you're making websites.
Note that CSS1 and CSS2.1 define :link
and :visited
to apply only to a
elements — the standalone Selectors standard (level 3 and up) instead defers to the document language, and in the case of HTML, the current definition above is provided by HTML5. What this means in theory is that browsers up to and including IE6 (not sure about IE7) don't support the link pseudo-classes on elements other than a[href]
, and that's because IE6 was designed to be CSS1-compliant, not CSS2-compliant.
What this means in practice depends on whether or not you use the link pseudo-classes to match area
or link
elements, and whether or not you support browsers dating back to IE7, in the first place. If you're like 99.9% of authors who don't use them with area
or link
elements, then this means absolutely nothing to you in practice.
What is the correct way? CSS Link Pseudo-Class
Whenever in doubt go to the specs. And here's an excerpt from the specs.
Note that the A:hover must be placed after the A:link and A:visited
rules, since otherwise the cascading rules will hide the 'color'
property of the A:hover rule
What you have is correct
a:link, a:visited, a:active {
color: #006699;
text-decoration: none;
}
a:hover {
color: #2089CC;
text-decoration: underline;
}
That's why this works.
This below would be incorrect.
a:hover {
color: #2089CC;
text-decoration: underline;
}
a:link, a:visited, a:active {
color: #006699;
text-decoration: none;
}
That's why this doesn't work.
Is there a reason to use a instead of a:link or a:visited in my stylesheet?
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.
It depends on your project. Strictly speaking, that is a mistaken assumption, as 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 mention 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:
Are they the same?
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) or a:any-link
(new in Selectors level 4), rather than a
. Note that it doesn't matter whether the attribute has a value or not, as long as it is present the pseudo-classes will match, 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...
Specificity
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.
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
(what I call generalized rules/selectors) are more specific than body > header > a
(what I call a specialized rule/selector), 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 that gets you all kinds of bad rep, right? So let's not do that.
Selectors level 4 gives you not one, but two solutions to this specificity problem. These solutions, new as they are, aren't supported in Internet Explorer and Microsoft Edge Legacy (the UWP/EdgeHTML/not-Chromium one), but thankfully there is a third solution that works in Internet Explorer 7 and later, which is a[href]
, the attribute selector I mentioned above.
1. The :any-link
pseudo-class
:any-link
has some history behind it which you can read in my answer to this question, but practically speaking, :any-link
serves as a catch-all for :link, :visited
. Its main purpose is to eliminate selector duplication, and for that reason there is in fact an equivalent in the form of :is(:link, :visited)
.
You can use a:any-link
in your specialized rule to match the specificity of the generalized a:link
and a:visited
rules, thereby allowing it to override them:
a:link {
color: red;
}
a:visited {
color: maroon;
}
/* 1 pseudo-class, 3 types -> specificity = (0,1,3) */
body > header > a:any-link {
color: white;
}
2. The :where()
pseudo-class
:where()
also has some history behind it, but essentially it's an analogue to :is()
with the exception that it zeroes out the specificity of its argument. See my answer to this question for an in-depth guide to how it works.
You can wrap the :link
and :visited
pseudo-classes in :where()
s to remove their pseudo-class specificity, thereby allowing them to be overridden by the specialized rule:
/* 1 type -> specificity = (0,0,1) */
a:where(:link) {
color: red;
}
/* 1 type -> specificity = (0,0,1) */
a:where(:visited) {
color: maroon;
}
/* 3 types -> specificity = (0,0,3) */
body > header > a {
color: white;
}
3. a[href]
(for older browsers)
Fortunately, if you need to support older browsers, 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!
/* 1 attribute, 3 types -> specificity = (0,1,3) */
body > header > a[href] {
color: white;
}
So which selector(s) to use?
This is all still incredibly 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
anda: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
anda:link
/a:visited
rules. If I need to apply the same property to both states somewhere, but I already have it in separatea:link
anda:visited
rules, I'll use one of the 3 options above to avoid specificity problems.
For example, here are the link styles I used in my site's Coming Soon page prior to its launch:
a {
text-decoration: none;
transition: text-shadow 0.15s 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;
}
a:focus {
outline: thin dotted;
}
/* ... */
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. This was for legacy reasons (as you'll see below, I originally posted this in 2012!), but of course it can be shortened to footer a:any-link
. However, the specificity-matching principle applies all the same.
Hopefully my advice helps you get a handle on the mess that is link styles.
Why bother with the L in the LVHA link styles?
Not all anchor tags necessarily have a href
attribute, so they're not all links. Presumably the :link
pseudoclass does not apply to anchor tags without a href
.
The :link pseudo-class does match visited links
It's a bit confusing but if you refer to the specification you will find:
UAs may therefore treat all links as unvisited links, or implement other measures to preserve the user's privacy while rendering visited and unvisited links differently.
This is what is happening here. The trick is to create some restrictions to avoid having a big difference between the styles of visited and unvisited links.
Technically, all the styles you will apply to a:link
will also apply to a:visited
unless you override them inside a:visited
and you are limited to the styles that you can apply inside :visited
so you cannot override everything:
You can style visited links, but there are limits to which styles you can use. Only the following styles can be applied to visited links:
- color
- background-color
- border-color (and its sub-properties)
- column-rule-color
- outline-color
- The color parts of the fill and stroke attributes
In addition, even for the above styles, you won't be able to change the transparency between unvisited and visited links, as you otherwise would be able to using rgba(), hsla(), or the transparent keyword. ref
Here is an example to illustrate:
a:link {
font-size:50px;
border:2px solid red;
color:black;
padding:20px;
box-shadow:5px 5px 0 blue;
display:inline-block;
margin:10px;
}
a:visited {
color:red; /* this will work */
border:5px dotted green; /* only the color will work */
background:black; /* This will not work because we cannot change transparent to opaque value */
/*All the below will not work*/
padding:0;
box-shadow:-5px -5px 0 purple;
display:inline;
margin:9584px;
font-size:10px;
}
<a href="www.something.comg">not visited</a>
<a href="#">visited</a>
CSS: a:link vs just a (without the :link part)
:link
selects unvisited links, that is: anchors with an href
attribute which have not been visited by the browser (for whatever definition the browser vendor has for "visited").
If it has :link
then it will never match <h1><a name="foo">A foo to be linked to</a></h1>
(Although you should be using <h1 id="foo">A foo to be linked to</h1>
these days.)
Aside from that, it does make it clearer what it is for.
a { color: orange }
a:link { color: blue }
a:visited { color: indigo }
a:hover { color: green }
a:active { color: lime }
<a>my anchor without href</a>
<br><br>
<a href="http://somelinkhere.com">my anchor without href</a>
Related Topics
How to Create a CSS3 Gradient in Opera
How to Tell Which Font Chrome Is Using
Reference a Class/Mixin Without Completely Importing the Less File
Center Twitter Bootstrap 3 Glyphicons in Buttons
How to Prevent :After Pseudo Element from Being Read by Screen Readers
Tweaking Bootstrap 2.0 for Semantic Markup
CSS Difference Between Attribute Selectors with Tilde and Star
Bootstrap SASS Variable Override Challenge
How to Set CSS Only for Specific Ie Browsers
How to Stop User Agent Stylesheets from Overriding My CSS
Are There Specific CSS Selectors Targeting Ie10
Position Element Over Background Image. But the Bg Img Changes Size with the Window. CSS
Cause Line to Wrap to New Line After 100 Characters
Make Second Div Appear Above First, Without Absolute Position or Changing HTML
How to Use Bootstrap 4 Flexbox to Fill Available Content