Links can be styled any which way you like to provide unique site navigation. These styles can be extended to pseudo states like :hover to create dynamic transitions. However, there are significant restrictions on styling links that the user has previously visited, limitations that are often unexpected and exasperating, especially for designers and developers who don’t understand the reasons why.

Visited Styles

Conventionally, user-agent stylesheets (the built-in styles that ship with the browser, and are applied by default to every web page) make text links blue and underlined. Of course, this can be changed:

a:link {
    color: currentColor;  
    font-weight: bolder; 
    text-decoration: none;
    border-bottom: 1px dashed;
}

This declaration styles the link using the color of the text that surrounds it, bolds it, removes the solid underline and substitutes a dashed underline using border-bottom. Similar treatment can be provided to visited links. For example, using Sass to lighten links that have been clicked on:

a:visited {
    color: lighten(currentColor, 30%);  
}

For links like those featured in this site’s , it would make sense to provide a more significant, progressive indication that a page has been read. You might assume that you could do so by simply adding generated content to the visited state: a checkmark, for example.

a:visited:after {
    content: "✓"; 
}

But if you test this, you’ll find that the tick mark does not appear. Adding generated content to the a:link state works… so why not a:visited?

Secrets and Limitations of the Visited Link

The requirement of the browser to track user history in order to style a:visited states led to security risks: analyzing visited links with getComputedStyle could reveal the entire browser history. For that reason, a:visited styles have very strict limitations:

  1. visited links can't be altered in a way that affects their layout (since that would allow you to query the DOM layout properties).
  2. Nothing can be changed that could involve an external file, which could be recorded on a server (which is why :before and :after are out-of-bounds)
  3. Nothing that could limit pointer events (mouse activity) on the link or elements underneath can be altered (meaning: no opacity or background-image changes)

That leaves just four properties with which to change the appearance of visited links:

  • color
  • background-color
  • border-color
  • outline-color

There's further restrictions inside this already limited set: because of the opacity rules, you can’t change the transparency of visited links: trying to style a:visited with rgba or hsla will either be completely ignored, or have the alpha component of the color ignored. In addition, the dependant state of elements after the link have restrictions: sibling connectors, such as a:visited + span, will act as if the link has not been visited at all, outside of changes to the four properties listed above. The rules also mean you can’t add, remove or change on a link in order to show a visited state.

Conclusion

While these restrictions do impose limits on styling visited links, they shouldn’t be too much of an issue so long as you keep them in mind; security holes continue to exist due to these vulnerabilities, although they are being attended to.

There is still the very interesting possibility of using blend modes in combination with background colors for visited links, an option that recovers many of the creative possibilities lost under the restrictions I’ve discussed here. I’ll discuss those in the next article.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.