CSS HacksPaul Irish maintains a comprehensive list of CSS hacks for various browsers. In reality, you'll rarely need to specifically target anything but IE. Here's a overview of the three most popular CSS hacks and which browsers they ' re supposed to target:
.foo {
color: black;
color: green\9; /* IE8 and older, but there’s more… */
*color: blue; /* IE7 and older */
_color: red; /* IE6 and older */
}
Note the use of the \9
CSS hack. Web developers noticed it could is used to easily target IE8 and older versions, so that's what they did. But then there is IE9, and as it turned out, the final IE9 release is still affected by this hack (despite my b UG report on the matter). All those CSS declarations this were meant to is for IE8 and earlier versions only, now got interpreted by IE9 as well. Needless to say, stuff broke, since IE9 doesn ' t need most of the ie8-specific CSS fixes.
This is the perfect example of an unsafe CSS hack.
Safe CSS HacksSo what constitutes a "safe" CSS hack? What makes me even think there is such a thing?
Let's face it-css hacks is still hacks. There's no-accurately predict how the future browser versions would parse these rules. But we can make an educated guess-some hacks is less hacky than others. A safe css hack is a CSS hack that:
Works in specific versions of a given web browser;
is unlikely to being parsed by all and browsers, including future versions.
Take _property: value
the hack, for example. The CSS 2.1 spec says the following:
Keywords and property names beginning with -
or is _
reserved for vendor-specific extensions.
A property name was an identifier.
In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters and [a-zA-Z0-9]
ISO 10646 characters U+00A0
and higher, plus the hyphen ( -
) and the underscore ( _
); they cannot start with a digit, TW o hyphens, or a hyphen followed by a digit.
So who's to say there would never is a property name starting with an underscore character? To quote the CSS3 spec:
Although [the underscore] is a valid start character, the CSS working Group believes it'll never define any identifiers That's start with that character.
Both the _property: value
and *property: value
hacks (as seen in the above code block) is examples of safe CSS hacks. They were discovered, identified as bugs, and patched in a browser update. Since then, it's very likely that Microsoft and other browser vendors added checks for these CSS hacks to their layout tes TS, to make sure no new browser version was shipped with a regression this significant.
If you discover a CSS hack in the latest version of a certain browser, it won ' t is a safe hack until an updated version of That browser was released where the parser bug is fixed. For example, some people (myself included) has been looking for the ie9-specific CSS hack. Recently, one is found, but we'll have to wait for least until the final IE10 release to use it, because IE10 could or may n OT be shipped with the same CSS parser bug. We can ' t risk repeating the history of the \9
hack.
Pros
You do not have the add conditional comments to every a single HTML page.
No additional HTTP Requests is being issued to get the ie-specific styles.
The specificity of your CSS selectors is preserved.
There ' s no need to repeat CSS rules-you can just add extra declarations (with the hacks) to the declaration block.
Cons
They ' re called CSS hacks for a reason-only use safe CSS hacks.
There ' s no safe CSS hack for IE8 (yet?).
Contrary to conditional comments, the most CSS hacks don ' t validate. But then again, CSS3 properties and Vendor-prefixed properties don ' t validate either.
Combining conditional classnames with safe CSS hacksSafe CSS Hacks is preferable to conditional stylesheets or classnames and what if do you have to write ie9-specific styles? By definition, the There won ' t be a safe CSS hack for IE9 at least until IE10 are released. Also, what's about IE8? There is the no safe CSS hack (that's I know of) that targets IE8 and not IE9. What does?
In the HTML, we can use a minimal version of the conditional classnames technique, like so:
<!--[if lt IE 9]><!--[if gt IE 8]><!-->
We can then use the as .lte-ie8
a styling hook in CSS selectors to target IE8 and older versions. Combined with safe CSS hacks, we can finally target IE8 and older versions without also affecting IE9:
.foo {
color: black;
}
.lte-ie8 .foo {
color: green; /* IE8 and older */
*color: blue; /* IE7 and older */
_color: red; /* IE6 and older */
}
This technique combines all the advantages of safe CSS hacks and conditional classnames, while minimizing the drawbacks.
About MeHi there! I ' m Mathias, a Web standards enthusiast from Belgium. HTML, CSS, JavaScript, Unicode, performance, and security get me excited. If you managed to read this far without falling asleep, you should follow me on Twitter and GitHub.
CommentsNicolas Gallagher wrote on 19th at 11:23:
Great summary! The last option is quite interesting.
There is a couple of other ways this people might use conditional stylesheets (not significantly different to the example You included, but with slightly different pros/cons).
One is wrapping conditional comments around stylesheets aimed at specific versions of IE to reduce the amount of Overridin G needed. IE6/7 is pretty similar so they can often get the same stylesheet. Not important (but still possible) to has valid CSS in a stylesheet that is only a, stable and well documented browsers WI ll ever see.
<!--[if IE 8]><link rel="stylesheet" href="ie-8.css"><![endif]-->
<!--[if lt IE 8]><link rel="stylesheet" href="ie-6-7.css"><![endif]-->
The other approach (brought to my attention by @bricecarpentier) requires a build script. It wraps every stylesheet in a conditional comment and serves IEs a CSS file that combines the default CSS with the Ie-spe Cific CSS. This means you don ' t incur a extra HTTP request in the old IE.
<!--[if gt IE 7]><!--><link rel="stylesheet" href="style.css"><!--<![endif]-->
<!--[if IE 7]><link rel="stylesheet" href="style.ie-7.css"><![endif]-->
<!--[if IE 6]><link rel="stylesheet" href="style.ie-6.css"><![endif]-->
But both these approaches has the same issues around making maintenance harder.
Thomas Deceuninck wrote on 19th at 11:52:
Interesting article mathias! But what does when is want to set a property specific for one browser? For example:
.foo {
color: red;
}
.ie7 .foo {
color: green;
}
If you use *
the prefix for it instead, IE6 would also be affected, right?
Nicolas Gallagher wrote on 19th at 11:53:
Oh, and one more problem with using conditional comments around the tag was that it throws IE into compatibility view Unless you set the X-UA-Compatible
header in a server-side config:https://github.com/h5bp/html5-boilerplate/issues/378
Luc De Brouwer wrote on 19th at 12:04:
I kind of disagree on the cons with the conditional stylesheets solutions.
The performance of the browser due to additional HTTP requests are something you can limit by targeting the specific browse R instead of using the ' LTE ' method. I find that maintainability increases with the different stylesheets because can keep all CSS ' hacks ' clearly separate D. Of course shouldn ' t need to go apeshit with the amount of needed ' hacks ', if that's the case you do a rubbish job Setting up the CSS framework etc. Also the solution Stoyan Stefanov suggested (the empty conditional statement) works like a charm.
However, this was an excellent write up!
Safe CSS Hacks