Conditional stylesheets vs CSS hacks? Answer: Neither!
From what I've seen a good number of developers these days are split between conditional stylesheets and css hacks.
You're used to seeing this:
<link rel="stylesheet" type="text/css" media="screen" href="css/style.css" /> <!--[if IE 7]><link rel="stylesheet" type="text/css" media="screen" href="css/ie7.css" />< ![endif]--> <!--[if IE 6]><link rel="stylesheet" type="text/css" media="screen" href="css/ie6.css" />< ![endif]-->
But probably also plenty of this:
div.infoBox { float: left; padding-right: 10px; _padding-right: 5px; }
CSS hacks to target specific browsers stay where the rest of your styles are, but they certainly don't validate. For sometime now, the standards community has rallied around conditional stylesheets as a solution to the validation problem.
There are a few problems with it though:
- Conditional stylesheets mean 1 or 2 additional HTTP requests to download
- As they are in the the <head>, the rendering of the page waits until they're totally loaded.
- Also - Yahoo's internal coding best practices do not recommend conditional stylesheets
- It can separate a single CSS rule into multiple files. I've spent a lot of time wondering "Where the eff is that rule coming from!?" when it turned out to be tucked away in a conditional stylesheet.
Here's my proposed solution:
<!--[if lt IE 7 ]> <body class="ie6"> <![endif]--> <!--[if IE 7 ]> <body class="ie7"> <![endif]--> <!--[if IE 8 ]> <body class="ie8"> <![endif]--> <!--[if IE 9 ]> <body class="ie9"> <![endif]--> <!--[if gt IE 9]> <body> <![endif]--> <!--[if !IE]><!--> <body> <!--<![endif]-->
Using the same conditional comments, we're just conditionally adding an extra class onto the body tag. This allows us to keep our browser-specific css in the same file:
div.foo { color: inherit;} .ie6 div.foo { color: #ff8000; }
Plus it totally validates and works in all browsers.
(Hat tip to Paul Hammond and Adam McIntyre for being s-m-r-t.)
<!--[if lt IE 7]> <body class="ie ie6 lte9 lte8 lte7"> <![endif]--> <!--[if IE 7]> <body class="ie ie7 lte9 lte8 lte7"> <![endif]--> <!--[if IE 8]> <body class="ie ie8 lte9 lte8"> <![endif]--> <!--[if IE 9]> <body class="ie ie9 lte9"> <![endif]--> <!--[if gt IE 9]> <body> <![endif]--> <!--[if !IE]><!--> <body> <!--<![endif]-->
Doug Avery of Viget points out he prefers to use this technique on the HTML tag, freeing the body tag for dynamic classes. That works just fine. Also it combo's really well with the Avoiding the FOUC v3.0 technique as well as Modernizr.
You fancy something different?
gt later and we're good.
2010.05.20: Turns out IE conditionals around css files for IE6 can slow down your page load time in IE8! Crazy, right? The solution here avoids that, as does forcing IE to edge rendering.
2010.06.08: And then…
Rob Larsen points out that when these conditional classes are applied to the HTML element, it doesn't block. No empty comment necessary. I think that's a new winner.
Follow me on twitter: @paul_irish