My IE hacks are better than your boilerplate and your conditional comments

I know after reading a headline like that you’re all heated and ready to battle. I, like you, am all about the lightest, most efficient HTML and CSS I can write. By efficient I mean it’s standards compliant, accessible, SEO optimized, speed optimized and all that other elite, ninja, guru mantra type of stuff. However, it seems the place where I find myself most at odds with my fellow developers is the discussion over the best way to address IE’s faults.

Up to the point of this writing, I have yet to find a compelling argument to stop using IE hacks in my main stylesheet. First of all, let’s get something out of the way… all of the solutions are hacks. Your boilerplate and your conditional comments are hacks. Deny it all you want, but any code you have to add to target a specific browser is a hack. If it wasn’t a hack you would write your code without it and all browsers would behave the same. Also, CSS validation doesn’t matter. Your boilerplate and your conditional comments may validate, but that means absolutely nothing. You don’t get better search engine rankings, your site is not more accessible and it doesn’t load any faster.

The only argument I’ve heard that seems to be relevant is that it may be easier to remove support for a specific browser, say IE 6, when that browser is no longer necessary to support. My first rebuttal would be that the time savings are negligible, if any. My second rebuttal would be that it’s much more time consuming and difficult to troubleshoot and fix issues today when that browser is necessary to support. So, for all the savings you might have one day when we can all finally say goodbye to IE 6, you’ve already spent a lot more time then I have troubleshooting and fixing issues.

So let’s get down to some details. My number one goal is always to make my HTML as pure as possible. Right off the bat, this means there’s no room for the boilerplate solution or conditional comments unless I can somehow justify adding that extra ugly to my code. Obviously, I haven’t found that justification yet.

In addition to adding ugly to my HTML, using conditional comments is also more time consuming and difficult to manage. It puts CSS in separate files. If something changes in your main stylesheet you always have to check the IE specific stylesheets to see if anything there is affected. And I’d be willing to bet, that at least once, you’re going to make a change to your main stylesheet, forget to update an IE specific stylesheet, and then spend an hour or so troubleshooting until you discover you simply need to remove or change that old IE specific rule. Then there’s that extra http request and file to load. I know, it’s only IE.

In the boilerplate solution you also have to add a whole lot of ugly to the top of your HTML document. Then, in your main stylesheet you have to add separate CSS rules to target specific browser issues. The separate CSS rules are similar to what you would have if you used conditional comments, except that here they provide the added advantage of being in the same CSS file as all your other rules. This makes troubleshooting and maintenance a little easier, but still not great. Again, I’d be willing to bet you’ll make a change to the main rule, forget to update the IE rule, and spend an hour or so troubleshooting before you figure it out.

IE 8, and I would assume IE 9, pretty much behave the same way other modern browsers behave (where hacks are concerned) so we don’t really have to worry about those. When I say I prefer IE hacks, I’m referring to the underscore and star kind of hacks. I know what you’re thinking, those are the worst kind. Let me see if I can persuade you to change your mind.

Example of the IE hacks:

.min_height_class { min-height:200px; _height:200px; } /* IE 6 hack */
.necessary_hack_class { *display:inline; } /* IE 7 and below hack */

First, these two simple hacks require zero extra ugly in my HTML. Remember? Number one goal? Since these hacks go in my main stylesheet, I don’t have to go back and forth between multiple files. Then, my favorite part, when creating code, everything goes into one rule. This makes it much easier to find when making changes or troubleshooting. Since well written code requires minimal hacks, the argument of a larger CSS file for the good browsers that some might make is also irrelevant. This argument doesn’t apply to the boilerplate since it actually adds even more bloat. And the extra size from the IE hacks is more than made up for with the savings from the extra loading that occurs with those conditional comments on every page load. The CSS file gets cached the first time it loads and that’s it. No more overhead.

So are you convinced yet? I’d like to hear from you. If I’m missing something that might change my mind, please let me know.

Disclaimer: I would like to make it clear that I have a great deal of respect for the creators of the boilerplate and those who prefer to use conditional comments. I just don’t agree with their methods in this regard.

HTML5 Boilerplate
Conditional Comments
IE Hacks

Here’s an excellent video from Nate Koechley on “Professional Frontend Engineering”. If you want to skip to -22:20 you’ll see he suggests using IE “Filter/Hack Syntax”:

You can leave a response, or trackback from your own site.

9 Responses to “My IE hacks are better than your boilerplate and your conditional comments”

  1. I agree. I really think these two filters (the underscore and star property hacks) are the best way to go when dealing with IE6/7.

    As a side note, you forgot to mention that when using a class (i.e. “.ie6″ to style an element differently in IE6) you mess up with the cascade as you increase the specificity of that styling for IE6.

  2. Personally, I agree. Actually, I’ve been working on a similar article for months now but never got around to finishing it — so thanks for this write-up!

    Btw, the ‘Boilerplate approach’ as you seem to call it is described in more detail here: http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ I like to refer to it as ‘conditional classnames’.

  3. Barney says:

    Good post Nathan. Particularly enjoyed the acerbic intro ;)

    I work in an environment where standard practice (among the other devs) is to use conditional comments and separate stylesheets. I know the deeper methodology of stacked per-property hacks, the pitfalls of multiple-file maintenance, the impossibility of applying a consistent method for non-IE browser-targeted styles, and the difficulty of retrieving the full front-end code served when hacks rely upon esoteric code in several places. In light of having worked with a lot of people of the opposite persuasion over the years, I might suggest that without tackling their gripes in a bit more depth, you’re at risk of preaching to the converted — the people I work with would need more convincing. If I might play devil’s advocate for a second:

    1) Whose hacks are most valid?

    Valid CSS will not ‘boost your SEO value’, has no effect on accessibility, or bring the serendipitous smile of the W3 God to bear in your daily life. The fact that Conditional Comments will pass HTML validation (and so will conditionally served CSS) is used as an argument though. My argument against this is that it uses esoteric proprietary parsing to achieve the desired functionality, effectively sweeping the essential hacks under the carpet. This means they are harder to track down: using a conventional DOM inspector, or site-wide validation, will not reveal anything untoward, when in fact your HTML is making use of silent hacks, and one or more files necessary to your full front-end are hidden.

    2) How extensible is the hack?

    What if new development requires IE7-targeted styles, while previously you only needed to isolate IE6? What if IE9 suddenly crops up as a requirement? What if you (heaven forbid) you need to specifically target a non-IE browser? In the first two cases, you need to create a new file and modify your markup templates. In the second, the method no longer applies.

    Take a look at this:

    .one-rule-to-rule-them-all {
    background: #000;
    background: rgba(0,0,0,.75);
    background: url(../../SiteImages/heroModule/background_black_75pc.png)\9;
    _background: #000;

    border: 1px solid #555;
    border-width: 1px 0 1px 1px;
    *border: none;

    -moz-border-radius-topleft: 6px;
    -ms-border-top-left-radius: 6px;
    -o-border-top-left-radius: 6px;
    -webkit-border-top-left-radius: 6px;
    border-top-left-radius: 6px;

    -moz-border-radius-bottomleft: 6px;
    -ms-border-bottom-left-radius: 6px;
    -o-border-bottom-left-radius: 6px;
    -webkit-border-bottom-left-radius: 6px;
    border-bottom-left-radius: 6px;

    -moz-box-shadow: 0 0 12px rgba(0,0,0,.5);
    -ms-box-shadow: 0 0 12px rgba(0,0,0,.5);
    -o-box-shadow: 0 0 12px rgba(0,0,0,.5);
    -webkit-box-shadow: 0 0 12px rgba(0,0,0,.5);
    box-shadow: 0 0 12px rgba(0,0,0,.5);

    height: 56px;
    *height: 58px;

    -moz-transition: width 0.1s ease-in-out;
    -ms-transition: width 0.1s ease-in-out;
    -o-transition: width 0.1s ease-in-out;
    -webkit-transition: width 0.1s ease-in-out;
    transition: width 0.1s ease-in-out;

    width: 172px;
    *zoom: 1;
    }

    Verbose! Confusing! But it’s all in one place, and it covers every single base. The parsing order within the single rule, along with hacks targeting all the versions of all the browsers as necessary, are the sum total of the styles applied to this element. It may take my colleagues a while to work out how this takes effect if they’re not familiar with some of the hacks involved, but once they’ve read this single rule and worked out the applications, they know. No other files. No markup hacks. THIS is the one place this element’s styles are defined. This is IT.

    3) Where is the code again?

    I wrote the code above as part of a dynamic module for an already large and complex site that’s been in production for years. As it is meant to be a drop-in plugin, it uses its own stylesheet. It also has its own markup templates and its own Javascript. Versioning, maintenance, easy extraction, are all a piece of piss thanks to this method. How would you handle it with conditional stylesheets? Build the hacks into existing IE-specific styles? Create even more files? How to handle the complex background property forking? The CC method is severely flawed as soon as you want to get this amount of control.

    Nicole Sullivan’s OOCSS grids module [https://github.com/stubbornella/oocss/blob/master/core/grid/grids.css] is a pertinent example. This tiny, succinct CSS file deals with massive cross-browser problems in dealing with fractional widths. How to implement this with CSs? Split the code? How? How then to easily update the file when she develops a superior version?

    Arguing for one of the other working method in terms of conceptual preference rarely works. Standardistas who believe that dumb validity trumps all, or who believe they’re making a meaningful and practically effective political statement by failing to cater for browser disparity as an integrated part of their coding workflow (and that that’s a pertinent argument to level against integral solutions), are usually much better at holding ground in such conversations.

    Problems they cannot resolve with their existing methodology — the edge cases, practical scenarios from potentially problematic projects, and cases where future- and past-proof, look-as-good-as-possible, polish-every-facet front-ends are a must — these are the situations that break the case.

    My two quid on the subject ;)

  4. LX says:

    I dislike the usage of invalid CSS, yet the conditional Classnames are useless clutter to me. So, for IE6-7, I use the * html / *+html selector hacks, and the dual id hack (just add “, #not#ie6-8″ to your selector) to deselect IE6-8 in my selections. Still I have not yet found a valid way to (de)select IE9.

  5. Dirk-Jan de Groot says:

    Interesting write-up, i see the advantage of having everything in one rule. However i am curious how you will target ie9 specifically

    Like @LX i haven’t found a hack to specifically target ie9, if indeed there is no hack for ie9 (except \9 that is not only targetting ie9) then this seems like an argument against your approach?

  6. nate says:

    Thanks to everyone who has contributed so far with comments and feedback.

    @Thierry – I appreciate your comments on my article, but even more so, I appreciate your articles on Block Formatting Contexts and Clearfix. Based on the number of popular websites using clearfix and <div class=”clear”>, it seems block formatting contexts may be the biggest secret in front-end development. That’s why I added the link to my Blogroll.

    @Mathias – I like ‘conditional classnames’ as the name for that solution. I was referring to it as the ‘boilerplate’ solution because of it’s association with the HTML5 Boilerplate. Thanks for adding the link to the original article.

    @Barney – My initial motivation for writing this was because I wanted supporters of conditional comments to convince me. I was hoping someone would respond with some facts to justify using conditional comments.

    @LX and @Dirk – I have not yet had the need to use a hack for IE8 and I expect more of the same from IE9. IE8 passes the Acid2 test which means we should be able to expect it to behave like other standards compliant browsers. I think now we have to train ourselves that we no longer need to figure out what the hack is for IE>=9.

  7. George says:

    Hey Nathan, thanks for writing this one.
    Just to contribute with a different idea, I used to work for a portal in which they applied both hacks AND conditionals. How?

    They used one global conditional IE file ( ), and in that they targeted each version using version-specific hacks.

    Personally? I go with Andy Clarke’s way of thinking: Universal IE Stylesheet/Progressive Enhancement.

Leave a Reply