Privacy and the CSS :visited Selector
I recently learned about some long-standing restrictions on styling using the CSS :visited
selector.
Now, in my defense, all of my web development work my entire career has been in the context of
web apps, where we don't typically style links based on whether they have been visited.
So, I never came across this issue until I was working on the styling for blog posts such as
this one, on mg5.dev. Since a blog post is a document, and not an
application, I wanted to preserve the default
affordance of styling visited links
differently from unvisited links. But, I didn't want to distinguish based on color, so my
initial thought was to use a different text-decoration-style
.
a {
text-decoration-style: solid;
&:visited {
text-decoration-style: dotted;
}
}
I thought this would be a nice subtle way of deemphasizing visited links. But, when I tried it, it didn't work?! Lots of fruitless debugging ensued. I tried different browsers, different syntaxes (thinking that perhaps there was some detail about using pseudo selectors in CSS nesting that I didn't know, since I've just recently started using native CSS nesting). Nothing worked!
See the Pen Privacy and the CSS :visited selector by Matt Sherman (@theminjam) on CodePen.
I finally found the reason! It turns out that way back when, before 2010, the styling of
visited links was used to track users' browsing history and leak a lot of information
about users. So, the CSS :visited
pseudo-class was restricted to only allow a limited number of
properties to be styled (from MDN):
color
background-color
border-color
column-rule-color
outline-color
text-decoration-color
text-emphasis-color
- The color parts of
fill
andstroke
The basic idea is that you can't style visited links in a way that would potentially alter the
layout of the page (since then window.getComputedStyle()
could be used to detect whether a
link had been visited).
This makes perfect sense! I had never thought about this specific concern before, but it's a great example of the delicate balance between functionality and privacy. Even seemingly harmless features can leak user information. Sure, the designer in me is disappointed that I don't have absolute freedom to style visited links in any way I want. But, the privacy advocate in me is glad that the designers and developers of the web platform carefully consider the privacy implications of every feature and put limitations in place to protect users.