I am sure you know what anchors are!
They are links, or hyperlinks to be more exact. They are Internet's basic construction material - they make the Internet information highway. We can travel through them and teleport to a different part of Web in a blink. We all know what they are. Right? Right. But just to be 100% clear - in HTML <link>
and <a>
tags are something different.
The <link>
element
I'm not going to write a lot about it. According to W3C:
The
<link>
tag defines a link between a document and an external resource and is used to link to external style sheets.
Also:
The element is an empty element, it contains attributes only.
This element goes only in the head section, but it can appear any number of times.
In HTML the <link>
tag has no end tag. Default styling in all browsers is display: none
. Most commonly you will see something like this in head section of HTML document:
<head>
<link rel="stylesheet" href="styles.css">
</head>
If you want to learn more about <link>
I encourage you to visit for example MDN Documentation. But for now - let's get back to business.
The <a>
element
This is the main character of this story. Famous anchor element, that creates a hyperlink to other websites, files, e-mail addresses or just to other location within the same page. As opposed to the <link>
it does need ending tag. It can have a whole bunch of attributes - the most widely known is href
. Without it our anchor won't lead us anywhere.
<p>Check out my <a href="http://twitter.com/BarbaraSzott">Twitter</a></p>
The other very often used attribute is target
- default value is _self
, which means "load content here, in the same browsing context as the current one"; other commonly used value is _blank
- "load content in the new browsing context", which usually means a new tab in the browser. I'm gonna stop here for a second to remind you about rel="noopener"
. You should consider adding this attribute while using target="_blank"
, especially for untrusted sources. Why?
Mostly for safety reasons - if rel="noopener"
is used we avoid exploitation of window.opener
API. Thanks to that when new window is created after clicking a link, potentially malicious code running on the new window won't access previous window through window.opener
attribute.
<a href="http://someoneswebsite.com" target="_blank" rel="noopener">Some website</a>
Ufff, that part was difficult! If you are interested read more about noopener
here.
Styling links - let's dive in!
Take a look at how simple link with default styling looks like:
Well, it is blue and underlined. Purple, if visited:
Nonetheless, typically this is not the appearance we want. Luckily for us - styling links is as easy as styling any other element. We can change color, add background color, borders, change font etc. Take a look at what is happening after changing some simple CSS for our <a>
element:
a {
padding: 15px;
background-color: #00acee;
border: solid 1px #008abe;
border-radius: 15px;
color: white;
text-decoration: none; /* remove underline */
}
...and the result:
Nothing too fancy. We can play around with it however we want. The fun begins with introduction of link states, and there are (basically) four of them.
Link states
:link
:link
state is CSS pseudo-class that basically means "unvisited". It matches every unvisited element with href
attribute (so not only <a>
).
But why use this pseudo-class, why can't I just style my anchor element? It's gonna apply either way, so what's the purpose of this state..?
There might be situations when you just want some general styling for anchor elements and special ones for unvisited links with, lets say, different classes (so different styling). On top of that - :link
attribute only matches elements with href
attribute. According to W3C spec:
If the
a
element has nohref
attribute, then the element represents a placeholder for where a link might otherwise have been placed, if it had been relevant, consisting of just the element’s contents.
So it's seems valid to use anchors without href
. Besides, in the galaxy far, far away, before HTML5 was introduced, anchors could have had name
attribute and no href
attribute for on-site navigation. So we could do something like this:
<a href="#aboutUs">Click here to know us better!</a>
<!-- some code... -->
<a name="aboutUs"></a>
<div>Something about us</div>
Now this technique is considered obsolete and should not be used - we can simply use IDs to do the same thing:
<a href="#aboutUs">Click here to know us better!</a>
<!-- some code... -->
<section id="aboutUs">Something about us</section>
:visited
This state is self-explanatory - it selects links that already have been visited by current browser. We can add some styles for :visited
to help users tell the difference between links they have or haven't clicked. Sounds simple - there is a catch though. It's again about security - listen carefully what MDN says about it:
Before about 2010, the CSS
:visited
selector allowed websites to uncover a user's browsing history and figure out what sites the user had visited. This was done throughwindow.getComputedStyle
and other techniques. This process was quick to execute, and made it possible not only to determine where the user had been on the web, but could also be used to guess a lot of information about the user's identity.
I've got goose bumps. For Pete's sake, it's just a link's state we want to style, and all of the sudden there is this issue. Fortunately it's been few years and now browsers take a good care of us. Nowadays the window.getComputedStyle
method (and similar functions, like document.querySelector
) will always return values adequate for unvisited links or page. End of topic, you won't get any styles with these method for :visited
links.
So what about styling? Can we do what we want? Not exactly - we have limited options here, and they include: color
, background-color
, border-color
, outline-color
and the color parts of the fill
and stroke
attributes. What's more - you can only change these styles if the link already has these properties set for its unvisited version. Let's see how it works...
For simplicity I'm going to separate general a
styles from its states' styles:
a {
padding: 15px;
border-radius: 15px;
text-decoration: none;
}
...now the states:
a:link {
color: purple;
background-color: yellow;
}
a:visited {
color: yellow;
background-color: purple;
}
Everything works just fine - unvisited link is purple with yellow background and visited is yellow with purple background, just as we wanted it to be.
But what if we decide that only visited link should have background color..?
a:link {
color: purple;
}
a:visited {
color: yellow;
background-color: purple;
}
You guessed right - it's not gonna work.
Color will be different, but background-color won't apply because unvisited version of that link doesn't have that property. If you gonna do opposite thing styles from :link
will apply to unvisited link as well.
a:link {
color: purple;
background-color: orange;
}
a:visited {
color: yellow;
}
What I've also found interesting here - if you don't specify border color it's gonna be borrowed from color
property. (This applies to other elements as well)
a {
/* some styles... */
border: 2px solid;
}
a:link {
color: purple;
}
a:visited {
color: orange;
}
No matter how you style your unvisited and visited links, have always in mind that they should be easily distinguished from each other.
:hover
:hover
is used to select elements when you mouse over them. It can be used not only on links but on all elements. It's important to remember that it might not work properly on touchscreens though. According to MDN:
The
:hover
pseudo-class is problematic on touchscreens. Depending on the browser, the :hover pseudo-class might never match, match only for a moment after touching an element, or continue to match even after the user has stopped touching and until the user touches another element. Web developers should make sure that content is accessible on devices with limited or non-existent hovering capabilities.
:active
This pseudo-class represents element that was activated (usually by the click). Link (or anything else, cause any element can have :active
pseudo-class) is active only for a fraction of a second, but if we change appearance of this state we will give visual feedback that element was indeed clicked.
LVHA rule
Now is a good time to remind you about very important aspect of our beloved CSS - specificity. (If your are not familiar with that topic - there is nice article about it on CSS Tricks) Every selector has one. If two selectors apply to the same element, the one with higher specificity wins, and if you add two declarations that points at the same element in your stylesheet with the same weight - the CSS will choose the latter. This is how the cascade works.
a {...} /* specificity = 1 */
a:link {...} /* specificity = 1,1 */
a:visited {...} /* specificity = 1,1 */
a:hover {...} /* specificity = 1,1 */
a:active {...} /* specificity = 1,1 */
That's why order is important, especially for :hover
and :active
pseudo-classes. The other thing that you can see here - selector with pseudo-class has higher specificity, so styles from a:link
might override these from a
.
If you want you can style differently :hover
for a visited link - just have in mind higher specificity:
a:visited:hover {...} /* specificity = 1,2 */
1.:link
will be overridden by any subsequent link-related pseudo-class
2.:hover
must come after :link
and :visited
3.:active
must go as a last one (otherwise it will be always overridden)
LVHA stands for:
- L -
:link
- V -
:visited
- H -
:hover
- A -
:active
It's also easy to remember as a LOVE-HATE rule. Using this order is considered best practice.
Summary
-
target="_blank"
should always go withrel="noopener'
- Visited and unvisited links should be easily distinguished - please remember not only about aesthetics but also (mostly) about readability, especially for users with impaired vision
-
:visited
pseudo-class have limited styling (color
,background-color
,border-color
,outline-color
and the color parts of thefill
andstroke
attributes) - Styles for
:visited
will only apply if unvisited version of that link also have them - The
:hover
pseudo-class can be problematic on touchscreens - Styling
:active
state gives user visual feedback that something really was clicked - LOVE-HATE rule
I hope you had fun reading this article - I sure did writing it. It is my first tech-post - hope to see some feedback from you! Cheers :)
Top comments (1)
Use the LoVe Fears HAte if you want to remember to reset the focus state.