Limitations on Styling Visited Links

on | 8 Comments

You might remember about a year or so ago, there was some discussion about the potential privacy issues caused by the CSS :visited pseudo-class. In a nutshell, it was discovered that this pseudo-class along with some scripting, could be used by websites to “sniff” your web browsing history.

You can read more about the problem and subsequent solution here and here.

It seems now that most of the latest versions of all browsers have taken measures to combat this issue. Fortunately, you can still style text links using the :visited pseudo-class. This is a good thing, and I hope we always have that ability. Visited links are a staple of the web, and they should remain.

A Simple Example

Because of the measures taken with regards to visited links, I thought I’d demonstrate some of the limitations that you’ll face if you decide to add some unusual styles to a visited link state.

Here’s the HTML I’ll be using:

Example Link

I’m using google.com for the example link because it’s the most likely link to already be visited. If you want the demo to work, make sure you click the link to ensure you have google.com in your history.

And here’s the CSS:

a:link {
	font-size: 40px;
	color: #222;
}

a:visited {
	display: block;
	width: 300px;
	height: 300px;
	border: solid 4px green;
	margin: 10px;
	padding: 20px;
	outline: solid 4px red;
	float: left;
	background: black;
	font-family: sans-serif;
	font-size: 100px;
	font-weight: bold;
	font-style: italic;
	letter-spacing: 20px;
	border-radius: 20px;
	text-decoration: none;
	color: limegreen;
}

a:hover {
	color: white;
	background: #333;
}

Yep, that’s right. I’m adding the kitchen sink to the :visited pseudo-class so we can see if any of those styles get rendered.

I’ve set up a simple JS Bin that you can view and mess with at your leisure. Try it in different browsers. If your browser has not yet plugged the :visited privacy bug, then you should see a huge ugly block link.

In browsers that have dealt with this privacy bug, the only line from the :visited declaration block that should be visible is the color property. Everything else will be ignored.

Which Browsers Allow History Sniffing?

I can’t possibly test on all browsers and versions, so if anyone has any feedback on testing, feel free to comment. But according to my tests, the browsers that allow the :visited styles to take effect are IE6-8 and Opera 11.50.

I’m assuming all versions of Opera recognize the :visited styles, but I can only currently test in that one. Maybe Opera has done something else to combat the history issue that still allows that browser to render the styles, but I really don’t know. But it does seem odd that Opera allows the styles.

And remember to visit the link in each browser otherwise you’ll get the impression that they all have the bug patched.

So, if you’re trying to do anything fancy with visited links, just realize that you may run into some bugs and it’s probably best to just stick to the color of the text, and nothing more — which is really all you’ll ever need for visited links.

Advertise Here

8 Responses

  1. Scott Vivian:

    Holy moly, you’ve done it again – I just had this exact issue a couple of days ago. In fact, I asked a question on Stack Overflow about it. The accepted answer gives more information and reasoning why this happens.

    One interesting anomaly I discovered: the background-color property can be overridden with the :visited selector, but only when there is also a real color defined on the :link selector.

    In other words, this does not show the yellow background on a visited link:

    
    :link { color: blue; background: transparent; } /* or no background set */
    :visited { color: purple; background: yellow; }

    But this does show the yellow background:

    
    :link { color: blue; background: limegreen; }
    :visited { color: purple; background: yellow; }
    
    • Well, I’ve been spying on you. :)

      Yeah, I just stumbled across this when doing research for a current writing project. Thanks for the heads-up on the background color anomaly.

  2. Apparently Chrome is the only one allowing color to be changed on :visited links—which after all does no harm.

  3. JulienW:

    Firefox allows color to be changed BUT using getComputedStyle it returns the color as if the link was not visited. That’s all that is really necessary to patch this privacy bug. So I think your article is somewhat wrong here, sorry.

    • Julien, I’m not sure why you say my article is “wrong”. The limitations on styling the visited links are (as far as I can see) due to the privacy issue. Yes, as you pointed out, technically, you can change the color on the visited link, but the JavaScript still reads it as if it’s unvisited, to prevent scripts from reading your history.

      Unless I’m mistaken, the other properties that do not take effect are that way in order to prevent any kind of history sniffing. But the color can be changed in order to allow the web to still have visited links in all browsers — which is good.

    • Scott Vivian:

      See the link I posted above. The other properties such as font-size *are* insecure, because even though Javascript would only return the original font-size, the visited state can get “leaked” through (for example) the width and height of the visited link.

  4. Had this problem at work just the other day. Had to kickback a visited link design that changed a background-image when visited. Sorry VD. Can’t do that.

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field. If you use keywords, your comment will be deleted, or your name will be replaced with the alias from your email address. No foul language, please. Thank you for cooperating.

Instructions for code snippets: Wrap inline code in <code> tags; wrap blocks of code in <pre> and <code> tags. When you want your HTML to display on the page in a code snippet inside of <code> tags, make sure you use &lt; and &gt; instead of < and >, otherwise your code will be eaten by pink unicorns.