A Blog Not Limited

to web design, standards & semantics

IE6 and Link Pseudo-Classes

Aug 03, 2008

Published in

While working on a freelance project a few months ago, I spent hours upon hours struggling with a bug in IE6. But a bug for which I could find absolutely no documentation. And a bug I had never seen before.

IE6 wasn't properly recognizing the styles I had assigned to my navigation links :hover pseudo-class.

After far too many hours (especially considering it was a freelance job), I discovered the solution to my problem.

The Background

I've been wanting to document this for a while now, in hopes of saving some other poor web professional from the wasted hours of pain and suffering.

At the core, I had marked up a primary level navigation using an unordered list (ul) containing links (a), and I had styled this list using my favorite image replacement replacement technique.

Simple. And it worked perfectly in every browser, except IE6.


As always, semantics dictated the use of an unordered list of links for my primary navigation:

  1. <ul id="primaryNav">
  2.       <li class="home"><a href="#" rel="home"><span></span>Home</a></li>
  3.       <li class="about"><a href="#"><span></span>About Us</a></li>
  4.       <li class="services"><a href="#"><span></span>Services</a></li>
  5.       <li class="projects"><a href="#"><span></span>Projects</a></li>
  6.       <li class="contact"><a href="#"><span></span>Contact Us</a></li>
  7. </ul>

Before you start questioning addition of the non-semantic span elements, keep reading. They are necessary for the CSS image replacement technique I used.


During my research for email design, I stumbled across Campaign Monitor's solution for image blocking.

This has since become my de facto approach for CSS image replacement (on the web and in emails). I like it because, even with the spans, it 1) gives me accessibility for screenreaders and 2) displays content even if images are turned off.

  1. #primaryNav {
  2.    margin:0 0 18px 0;
  3.    list-style-type:none;
  4. }
  5. #primaryNav li {
  6.    float:left;
  7. }
  8. #primaryNav li a {
  9.    display:block;
  10.    position:relative;
  11.    height:53px;
  12.    width:50px;
  13. }
  14. #primaryNav li a span {
  15.    position:absolute;
  16.    top:0;
  17.    left:0;
  18.    height:53px;
  19.    width:50px;
  20.    background: url(/images/navigation.png) no-repeat 0 -53px;
  21. }
  22. #primaryNav li a:hover span {
  23.    background-position: 0 -159px;
  24. }
  25. #primaryNav .home a:hover span {
  26.    background-position: 0 -159px;
  27. }
  28. #primaryNav .about a {
  29.    width:80px;
  30. }
  31. #primaryNav .about a span {
  32.    width:80px;
  33.    background-position: -53px -53px;
  34. }
  35. #primaryNav .about a:hover span {
  36.    background-position: -53px -159px;
  37. }
  38. #primaryNav .services a {
  39.    width:69px;
  40. }
  41. #primaryNav .services a span {
  42.    width:69px;
  43.    background-position: -132px -53px;
  44. }
  45. #primaryNav .services a:hover span {
  46.    background-position: -132px -159px;
  47. }
  48. #primaryNav .projects a {
  49.    width:71px;
  50. }
  51. #primaryNav .projects a span {
  52.    width:71px;
  53.    background-position: -200px -53px;
  54. }
  55. #primaryNav .projects a:hover span {
  56.    background-position: -200px -159px;
  57. }
  58. #primaryNav .contact a {
  59.    width:82px;
  60. }
  61. #primaryNav .contact a span {
  62.    width:82px;
  63.    background-position: 100% -53px;
  64. }
  65. #primaryNav .contact a:hover span {
  66.    width:82px;
  67.    background-position: 100% -159px;
  68. }

The Problem in Action

Before going into further detail, you can see the problem for yourself. Obviously, you need to open this link with IE6.

As you can see, IE6 basically holds on to the :hover style once a link is hovered over. It doesn't go back to the plain a or :link styles as it should … and as all other browsers do (I hate you, IE6).

The De-Bugging Process

Once I discovered this problem, I hit my go-to IE6 CSS bug resources:

Zip. Zero. Zilch. Fuck.

Then I searched Google exhaustively. Again, nothing.

So then I started actually de-bugging. For me, this entails:

  1. Validate markup
  2. Validate CSS
  3. Isolate the markup by creating a new page with only the markup in question
  4. Isolate the CSS by embedding (no linked files) the styles associated with the markup
  5. Contact my friends to see if they know of anything
  6. Drink a beer (or ten) and step away from the problem

Spaghetti Method

So with no luck searching and no luck de-bugging, I started throwing everything and anything at the problem, and hoped something stuck.

To this day, I have no fucking clue what eventually led me to the solution. I just remember going through my original CSS file line by line when I noticed something: I had neglected to define basic link styles.


As it turns out, I had modified my normal workflow when creating my main CSS file. Normally, I define the basic layout and text styles — such as those for h1, p, a, etc. — before styling more specific elements.

For some reason with this project, I chose to dive right into styling elements to which I'd already assigned classes and ids, including the styles for my primary navigation. I just figured I'd go back and get the basic styles in place later.

Once I noticed this, I threw in some CSS for unspecified links and voilà it resolved my IE6 problem. I swear I almost fell out of my chair. Seriously, who would've thought that this would be the source of the problem?

Don't believe me? See for yourself.

Even Weirder

I also discovered that the styles I applied for my plain links had to mirror the same pseudo-classes organization that I was using for my #primaryNav styles, where there was one declaration for the "standard" link pseudo-classes (:link and :visited) and another declaration for the dynamic pseudo-classes (:hover, :focus and :active):

  1. a, a:link, a:visited {
  2.    color: #5f5143;
  3. }
  4. a:hover, a:focus, a:active {
  5.    color: #000;
  6. }

I can't begin to speculate why this is a problem in IE6, why my solution worked or why I had to mirror the declaration structure.

I just know this is so fucking typical of IE6. So much so, it is almost laughable. Not quite, though, because I really did waste a ton of time on this.

Minor IE6 CSS Consideration

Once I discovered this completely simple solution to what I still think is a ridiculous problem (I hate you, IE6), I noticed one other inconsistency in IE6 (gasp!). Fortunately one I easily resolved.

The image replacement technique used causes IE6 to not display the proper cursor on the navigation links, so I added cursor:pointer to the link declaration. Ta-dah!

Why Bother?

Now that IE7 is out and IE8 is around the corner, you may wonder why even bother with IE6. Well, I ask myself that same question every single day.

The reality is that IE6 still holds a significant piece of the market. How significant really depends on the audience, industry and site.

For me, I have to factor in IE6 at work because my company still hasn't allowed a company-wide upgrade to IE7. And for this particular freelance job, the audience (not to mention the client) primarily uses IE6.

In the End

It still isn't clear to me if this is a bug in IE6 or a problem with my CSS workflow. The solution wasn't a hack by any stretch of the imagination, but it seems to me that there shouldn't be any required styles, regardless of the presence of styles with greater specificity.

The fact that every other browser rendered the styles correctly suggests to me that the problem lies with IE6 and how it reads specificity … or something along those lines.

But I fully admit that I have never neglected to style plain links in my main CSS before. And since I couldn't find any documentation out there, I'm assuming no one else has encountered this particular issue because they don't make that same oversight.

I still hate IE6, though.

HTML5 Cookbook

Interested in HTML5?
Get the Cookbook!

I was a contributing author for HTML5 Cookbook, available for sale on Amazon! Get yours now! (I hear chapters 1, 4 and 5 are particularly good.)

P.S. Don't forget my book Microformats Made Simple is still for sale!


Share the Love

Ian's Gravatar

Ian opines:


Great post, Emily. You have been sitting on this post for a while. ;-)

Regarding browser market share… for our company site, IE (all flavors) currently (rolling 30 days) comprise 79.76% of all non-support-site traffic. Firefox is 16.76%. Of the Intarweb Exploders, 56.84% are IE6 and 43.07% are IE7. Oddly enough, third place is IE 5.5 (gasp!), not IE8.

Jen's Gravatar

Jen opines:


Well, for a new kid on the block like me this is very helpful. I can’t always say I have the most organized work flow, especially when using more advanced CSS like you describe. So for all of us out there trying to learn, thanks.

daniel's Gravatar

daniel opines:


Yes, with ie6, in my experience it is not enough to style links purely using class. You have to use a specific id in your stylesheet in order to avoid any ie6 inheritance issues.

Commenting is not available in this channel entry.

The Coolest Person I Know

Emily Lewis

Yeah, that would be me: .

I'm a freelance web designer of the standardista variety, which means I get excited about things like valid POSH, microformats and accessibility. I ply my trade from my one-person design studio in Albuquerque, New Mexico 87106 USA.

A Blog Not Limited is my personal blog where I pontificate about web design, web standards, semantics and whatever else strikes my fancy. Head on over to Emily Lewis Design if you'd like to see my work or, even better, hire me.


I Tweet, Therefore I Am

Follow @emilylewis on Twitter!