Grow your CSS skills. Land your dream job.

“Checkmark” Your Visited Links with Pure CSS

Published by Chris Coyier

Due to user privacy issues, more modern browsers severely limit how you are able to style :visited links, which renders this article rather useless. You can read more about it here.


Web browsers know which links on a page have been visited by a user (until the cache is cleared out, that is). It is up to you the designer to take advantage of that web browser's knowledge, if you choose to do so. I'm sure you don't need to guess, this all happens with CSS. If you choose to not apply any styling to links (<a> elements or "anchor" elements), most browsers have default styling that applies. Typically, blue with underline. In Firefox, visited links become purple with underline.

You can take control of the styling of these anchor elements in your CSS by targeting them with pseudo classes. The goal of this tutorial is to get a check mark preceding visited links for a nice visual indicator. You can see an example of this live on Mike Davidson's blog. We will be targeting the a:visited pseudo class, but I will include information on the other anchor pseudo classes later in this article.

The perfect scenario for a pseudo-pseudo class

Since the goal here is to add the check mark to the links, this is a perfect scenario for the "before" or "after" pseudo classes in CSS. These classes allow you to literally specify page elements and add content to them, right from the CSS. Here is an example:

blockquote:before {
    content: "From the article: ";

This will literally put the text "From the article: " before every single blockquote on your page. Does this muddy the waters between the separation of design and content? Well... maybe a little. But not really. Just don't think of these content additions as content, think of them as flair, a little something extra for your web design. Because this exists solely in your CSS, this isn't content that screen readers are going to see or that will make it into your RSS feed.

Do you see where I am going with this pseudo-pseudo thing?

a:visited:before {
   content:  "";

We can target visited links and then add content before this with this CSS statement. Now all we need to do is get a check mark in that content. This isn't quite as intuitive. You can't use regular glyphs here like you can in HTML. For example, putting &reg; will not work in most browsers. You will actually see that string of characters instead of the registration glyph. Instead you use a forward slash and the ASCII code for the character. 2713 is the code for a check mark. So we have:

a:visited:before {
   content:  "\2713 ";

Tada! Done! This works perfectly in Firefox, Opera, Safari and.. Oh, wait...

Internet Explorer 6 doesn't support non-anchor pseudo classes

Awww, that sucks. This is where you need to ask yourself if you care or not. I popped open Mike's blog to see if he dealt with the IE6 problem. Nope, his links just go grey and underline when visited, but forgo the check mark thing. This is a completely acceptable form of forward-enhancement in design. You use a good browser? Good for you, you get extra nice features. You use an old crappy browser? That's OK, the page will still look and read fine.

But I have my heart set on this now, let's get this done! We can do this without the use of the :before or :after selectors, let's just use the plain a:visited (which IE6 understands just fine), and style that to include the check mark. It's not going to be text, but we'll just make that check mark into a graphic and include it that way, check it out:

a:visited {
     padding-left: 14px;
     background: url(images/checkmark.gif) left no-repeat;

Now we can celebrate for real. Hooray! This works well in all browsers. Check out the example page.

The other anchor pseudo selectors

  • a:link - This one isn't used a whole heck of a lot because it's sort of redundant. If it's an anchor element it's a link already. The reason it exists is for specificity. You can declare styling here that will not cascade to other anchor styling like it would if you just styled the a element alone.
  • a:visited - You know this one by now. This is what you use to style links that have been visited, as decided by your browser.
  • a:hover - This is the most common. Use this to style the rollover state of your links
  • a:active - I have to admit I was confused by this one for a long time. This is the best way for me to explain it. The active state is what you see if you were to click and hold on a link. You typically will not see the active state for very long, as the page is likely whisking you away to another page. I think it can be fun for a little flair though. Sometimes just a color change on the active state is a nice little touch.

Here is a nice way to remember what the anchor pseudo classes are.


  1. Permalink to comment#

    I used a similar technique for one of my ways to style nofollows, along with a rather un-semantic use of image substitution techniques.

    Its impressive how many interesting ascii characters there are from ticks to skull and crossbones

  2. I have always avoided using pseudo-selectors due to the non-existent IE support. However, your article changed my mind. Thank you.

  3. Correction … I have always avoided the :before and :after pseudo-selectors because of lack of support in IE

  4. Chris
    Permalink to comment#

    That’s really a good way to do it since IE6 and below doesn’t support it.

  5. @Tim Nash: Haha, I love the idea of putting a little condom around nofollow links. You could actually literally wrap the entire link in an expandable condom graphic with a sliding door technique, that would be pretty slick.

    @Dennison Uy & Chris: Thanks, glad you liked the idea!

  6. Permalink to comment#

    The only “problem” with this, would be when visitors use a public terminal. For instance at a netcafé or an airport. A lot of systems don’t clear cache nor site history as it should, so you’re left with the “already been on this site”-styles.

    Then the user would be on the page, wondering what the heck all the check marks were for.

    But then again, that is a minor “problem”.

  7. chris
    Permalink to comment#

    ^^ Koew…

    You would have that problem with any a:visited style (pseudo or not) on a public or multi user browser, unless you choose to not have a a:visited style. But where’s the fun in that!

  8. Permalink to comment#

    Great tip. Thanks!

  9. Great article Chris!

    The “trick” itself (the css) isn’t anything new but the concept of placing a checkmark before the link is both creative and useful.

  10. Permalink to comment#

    that’s really cool that it adds the checkmark dynamically if you open the link in another window or tab

  11. Permalink to comment#

    Crazy, this doesn’t work in my firefox. Everything’s fine in IE though.

  12. bender
    Permalink to comment#

    people should be smart enough to know what links they have clicked on.

  13. Nice article but you underestimate the use of the active at the end there.
    Active and focus states are very useful to keyboard only users.

    If you tab through links then setting focus state similar to the hover state enables you to easily see where you are. (Follow the carret)

    Unfortunately IE doesn’t support focus properly but does active.

    Therefore it is usually best to state active, focus and hover to the same or similar settings.

  14. JM
    Permalink to comment#

    Nice tip !
    I just tried it but there is a problem with the image links i use in a top menu bar. Checkmarks before them are not usefull or nice i think.
    Do you have any idea about that ?
    I tried that with no luck :
    .imageLink {
    padding-left: 0px;
    background: none;

  15. @mike foskett: You are absolutely right, I have underestimated the importance of active links. I think perhaps active states should be styled differently from hover states to an even bolder / more drastic color change, etc. Reason being that pressing the tab key to jump around between links on a page, you just are never sure where that next link is going to be and it really should jump out at you visually if possible. Whereas hover styling may not need to be as drastic a change to be effective.

    @JM: Yes, you make a good point that I should have made in the article. You are going to want to get more specific than I did about which anchor links you affect with this technique. If you have a “main content” area of your site (e.g. The typical WordPresss area) you could “checkmark” only links in that area with:

    .post a { CHECKMARK CSS }

    I think almost anyone using this technique will want to do something like this, rather than apply it to all links on their site because, as you say, it will look screwy in things like main page navigation.

  16. JM
    Permalink to comment#

    Thanks Chris, you’re right about the cutting up of parts.
    In fact i use the same padding way to identify links by document, icons of pdf, word or other formats or even mailto at the right of links. And, to avoid it on image links i use the class i mentionned
    .imageLink {
    padding-right: 0px;
    background: none; }
    which worked very well but not with the padding-left: 0px i added for the checkmarks.
    I’m not expert in css but it seems that the mix of the tips for the same link doesn’t work.
    Still trying to find a way…

  17. So correct me if im wrong BUT Mikes example includes NO image and just script??? WOW now thats cool…
    I always thought it was an image.

    Only question: Is it effective for the common user?

  18. @Jermayn Parker: Yep, I think Mike’s checkmarks get added via script with a similar technique to the after selector adding a content glyph. The only reason I think script is because poking around in his CSS, I don’t see any :after selectors. The advantage to doing it with an image is you don’t need that and it works in all browsers, like I mentioned in the article.

    Is it effective for the common user? Do you mean, does it work for common users? Yes, it works the same for any visitor. Do you mean, will common users find it useful? I dunno, it puts a checkmark next to visited links. I think that’s pretty useful. Even if a user never notices it, it’s not hurting them in any way.

  19. OK, ill try andf explain what i mean, sorry!

    Is the tick effective for the common user? The common user is set in their ways on what they use on the Net (back, underline for links etc) and does the tick effect that???

    I personally prefer the tick BUT im just a little worried that the tick may cause more harm than good.

  20. @Jermayn Parker: By “tick” do you mean the checkmark? Functionally, it doesn’t change anything, so I can’t imagine it causing any harm.

    Since it’s a background image you can’t even select it like you could by adding an real character, which is another advantage to the image technique and confirms how this is just an aesthetic add on, not a functional adjustment.

  21. Permalink to comment#

    oh that’s nifty. I’ma have to give that a try on my new design.

  22. Permalink to comment#

    Great article and a great look but it doesn’t work in my Firefox either. In IE it works fine. Maybe some Firefox extension interfering?

  23. Matthew
    Permalink to comment#

    Hey thanks,. nifty little idea. And it works fine for me in FF 5.0

  24. Permalink to comment#

    I’ve been pondering this article today, wondering about the usability effects that putting this “feature” in would have. I peered at the page (the example one and my own test) for a little while to figure out what this new pertinent information supplies to the user experience.
    From my point of view, i was slightly confused; i didn’t quite gain anything from it.

    Symbolically what does a tick (checkmark) mean to me? Well I guess it means “yes” or “done”. But this is the world wide wibble wobble. What does it mean here?
    A “good” link, or “the site works”, or feature list ticks?

  25. @James: In a quite literal way, the checkmark says “Hey, you’ve already been to this link”. I think that can be quite useful when browsing a page and you see a link. Links can have any anchor text the writer desires, but if it link goes to the same place, your web browser knows that and will mark it as visited. That way, if you’ve already clicked the link “See the original article.” and there is a “Learn more.” link later in the article that goes to the same place, you’ll be notified you’ve already seen that.

  26. Had some problems in firefox, hope i can fix them… But a great idea, thanks very much!!1

  27. Permalink to comment#

    @Chris: Don’t get me wrong I know what YOU’re trying to imply with the use of the visited link background image, however I don’t feel this is a clear indication to the user that that’s what is going on. Hence I did a quick check round (via user questioning) and it seemed to be the concensus was that it implied the link was “ok”, or “working”, which I suspect is different to what you wanted to convey. It would appear to be quite obscure from a usability perspective.

  28. Permalink to comment#

    yo, what a good idea, i will do it for sure,

    thanks buddy!

  29. Permalink to comment#

    Thanks for this great idea!!! Please give us more of that!!

  30. Permalink to comment#

    Thanks for the great tip!!!

  31. Perfect Example, let’s me try it

  32. I love what you have done with this template, gets a 10 out of 10 from me.
    I’ll add a link to one of my sites so I’ll be easy to come back for some more css tips.

  33. Great Information. Does this work on firefox ?

  34. N.P

    If I’m not mistaken the active link state shows up in the original page if your link opens a new active page. (ie using _blank). It will show if both pages are still open so if you go back to the original page you know what linked you clicked on to open the pop up page.


  35. Does this still work well with Firefox 3 and IE8? I have noticed with Firefox 3 that a lot of websites look very different and some of them aren’t even working properly. I can’t make up my mind if this is FireFox 3’s problem or the web designer’s lack of attention. One of the reasons why I always enjoyed Firefox was because any website would work pretty well (even if coded badly) but this seems to have changed in the new version.

  36. Wow! I thought there’s no more hope for pseudo-selectors. In fact I used to eliminate or completely disregard projects which involve those because I have problems with them and with browser issues for that matter.

  37. Hi Chris,Just wanted to comment on what a nice design you have on your site. I especially fancy your tags on the bottom, very cool. Great editor too!
    Best Regards,
    Founder of

  38. O
    Permalink to comment#

    The a:visited:before doesn’t seem to work anymore (at least not on Safari or Chrome)
    Can anyone confirm?

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".