Defeating IE6 with Emphasis – The Underscore Hack

One of the perennial complaints of web designers, particularly those who write CSS, is dealing with bugs in Internet Explorer. Though IE7 has improved things a great deal, there is a sizeable chunk of the browsing public who are still stuck with IE6.
There are a few different ways to work around IE6's bugs. (Conditional comments, for example.) My personal favorite, for simplicity and ease of use, is the underscore hack.
What is it?
What the underscore hack does is feed a CSS property only to IE6. In this example, IE6 receives a background color of black, while all other browsers (including IE7) receive a background color of white.
#page {
background-color: white;
_background-color: black;
}
How does it work?
IE6 has an implementation bug which causes it to read CSS properties starting with an underscore as if the underscore wasn't there. So with the previous example, what IE6 sees is this…
#page {
background-color: white;
background-color: black;
}
And since the last property declaration overrules previous ones, IE6 applies black.
Other browsers, not having this bug, don't even register the second property, leaving them seeing only this…
#page {
background-color: white;
}
An important point
Because of this, whenever you want to take advantage of the underscore hack, you must always place the underscored property after the non-underscored property.
When should it be used?
Like all hacks, the underscore should be used sparingly. If you need to feed a large number of properties to IE6, or include IE7, conditional comments is a better choice. But if you have just one or two problems that need a quick fix, the underscore hack might be just what you need.
Update: To clarify, despite the fact that the W3C validator will throw an error, the underscore hack is still valid CSS 2.1.
What our readers said
Interesting but would css using that still validate?
I think it might even be cleaner to just override IE6’s css in a separate block.
/* All browsers */
#page {
background-color: white;
}
…
/* IE hacks */
#page {
_background-color: black;
}
… (other IE hacks)
The CSS would still remain valid, since the underscore is permitted by the spec. However, the W3C’s automated validator will (incorrectly) say that it is invalid.
Putting the IE hacks in a separate block could be a good idea, depending on the circumstances. If I need to use them, though, I tend to keep them next to the property that I’m overriding so that when edits are made in the future, I’ll know to change both values.
If I have to use any “hacks” for IE, I prefer to just use IE conditionals. Either way will work, I just like conditionals better because I find it a little easier. Once all browsers have standards support and we can finally stop developing for IE6, all I need to do is simply delete the IE stylesheet, rather than dig through code to find the hacks to remove. That’s supposing of course that you’re using a ton of hacks in your stylesheet that you’d have to find. In my experience, most layouts can be accomplished without hacks at all.
@Deron: That’s been my experience as well. I rarely use hacks, but if I do need one for IE6, the underscore is my first choice because I find it the most natural fit for my style of CSS coding. It also means that I can do all of my work in the stylesheet rather than having to edit the HTML.
I think this is more a fix in IE7 than a hack in IE6. All versions of IE will ignore invalid characters when parsing CSS. For IE7 though, the underscore is treated differently. IE7 will not parse a CSS style that begins with the underscore, thus giving you a way to isolate IE6 and IE7 hacks. It’s worth noting that is only true if the webpage is not being rendered in Quirks mode. When in Quirks mode, IE7 will parse the underscore in the same way that IE6 does.
Thanks for the post – an interesting problem I’ve run into is being able to determine whether the workaround is working or not when developing in IE 8. The _someDivTag won’t render in Compatibility mode of IE8. The good news is that the method worked beautifully when I was able to test the results with an older laptop locked into IE6. So moral of the story, if the workaround isn’t showing any effect in Compatibility mode of IE8, no worries, it probably will with an actual IE6 browser.