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.
The XHTML
As always, semantics dictated the use of an unordered list of links for my primary navigation:
<ul id="primaryNav">
-
<li class="home"><a href="#" rel="home"><span></span>Home</a></li>
-
<li class="about"><a href="#"><span></span>About Us</a></li>
-
<li class="services"><a href="#"><span></span>Services</a></li>
-
<li class="projects"><a href="#"><span></span>Projects</a></li>
-
<li class="contact"><a href="#"><span></span>Contact Us</a></li>
</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.
The CSS
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 span
s, it 1) gives me accessibility for screenreaders and 2) displays content even if images are turned off.
#primaryNav {
-
margin:0 0 18px 0;
-
list-style-type:none;
}
#primaryNav li {
-
float:left;
}
#primaryNav li a {
-
display:block;
-
position:relative;
-
height:53px;
-
width:50px;
}
#primaryNav li a span {
-
position:absolute;
-
top:0;
-
left:0;
-
height:53px;
-
width:50px;
-
background: url(/images/navigation.png) no-repeat 0 -53px;
}
#primaryNav li a:hover span {
-
background-position: 0 -159px;
}
#primaryNav .home a:hover span {
-
background-position: 0 -159px;
}
#primaryNav .about a {
-
width:80px;
}
#primaryNav .about a span {
-
width:80px;
-
background-position: -53px -53px;
}
#primaryNav .about a:hover span {
-
background-position: -53px -159px;
}
#primaryNav .services a {
-
width:69px;
}
#primaryNav .services a span {
-
width:69px;
-
background-position: -132px -53px;
}
#primaryNav .services a:hover span {
-
background-position: -132px -159px;
}
#primaryNav .projects a {
-
width:71px;
}
#primaryNav .projects a span {
-
width:71px;
-
background-position: -200px -53px;
}
#primaryNav .projects a:hover span {
-
background-position: -200px -159px;
}
#primaryNav .contact a {
-
width:82px;
}
#primaryNav .contact a span {
-
width:82px;
-
background-position: 100% -53px;
}
#primaryNav .contact a:hover span {
-
width:82px;
-
background-position: 100% -159px;
}
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:
- Validate markup
- Validate CSS
- Isolate the markup by creating a new page with only the markup in question
- Isolate the CSS by embedding (no linked files) the styles associated with the markup
- Contact my friends to see if they know of anything
- 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.
WTF?!
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 class
es and id
s, 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
):
a, a:link, a:visited {
-
color: #5f5143;
}
a:hover, a:focus, a:active {
-
color: #000;
}
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.
♥ Share the Love