How to Use Conditional Comments for Better CSS

I’m a new contributor to the SitePoint blogs and will mostly be covering front-end development and Semantic Web technologies. I’m looking forward to participating in the SitePoint community!

Sometimes it’s the simplest things that go unnoticed for the longest time. Case in point, while catching up on some WSG reading tonight, I saw a link to Paul Hammond’s Conditional classnames for Internet Explorer. In a sentence, he shows how using conditional comments to customize the <body> element’s class name can be used to simplify CSS selectors for a number of advantageous purposes.

The code Paul showcases looks like this:

[T]his HTML:


<!--[if IE ]>
  <body class="ie">
<![endif]-->
<!--[if !IE]>-->
  <body>
<!--<![endif]-->

with CSS that looks something like:


div.foo {
    color: inherit;
}
.ie div.foo {
    color: #ff8000;
}

So simple and yet so potentially powerful. Some of the advantages to using this, a technique that’s been technically available since the inception of IE’s conditional comments “feature” since IE5—albeit not used widely, if at all—include:

  • Avoiding the need for an extra IE-only style sheet, improving site performance by reducing HTTP overhead (as Paul mentions in his post).
  • Eliminating (traditional) IE-specific CSS hacks from style sheets entirely. This could be accomplished by using more specific conditional comments with a wider set of class names. For example, the following code could be used to specifically identify IE7 in the HTML:
    <!--[if IE ]>
      <body class="ie">
    <![endif]-->
    <!--[if IE 7]>
      <body class="ie ie7">
    <![endif]-->
    <!--[if !IE]>-->
      <body>
    <!--<![endif]-->
    

    in which case CSS selectors prefixed with either .ie or .ie7 would be able to target it.

  • Other technologies (beyond CSS) that interact with the HTML document will be aware of their IE-specific environment. JavaScript springs to mind. Yes, yes, I know browser sniffing is much worse than capability-based object detection, but the fact remains that sometimes IE won’t give you “the whole truth and nothing but the truth….”

There are certainly a number of “philosophical” or “stylistic” points to be made with such a technique, such as that segregating hacks into their own files is a good thing for maintainability. My personal opinion on such things is that a hack should be made as obvious as possible so you fix it at the first opportunity you get, rather than forget about it. This is why I’ve long preferred to put the * html hack to target versions of IE less than 7 directly after the CSS rule they are overriding, but again, this is often a stylistic choice.

I almost feel bashful to admit that I’ve not encountered this technique before. Of course, that fact alone tells me that it’s entirely possible to implement high-fidelity web designs successfully without this technique. Nevertheless, the notion of conditional class names for IE certainly raises some interesting questions with regard to how IE-only code may be simplified, and I think any technique that improves code comprehension is worth at least a second look.

Win an Annual Membership to Learnable,

SitePoint's Learning Platform

  • Keith

    Interesting technique, but I’m not sure it’s one I’d endorse or use with co-workers / clients. Currently I support Safari 3, Firefox 2.x & 3.x, and Internet Explorer 7.x & 6.x with my designs.

    In the few times where I’ve run into problems (typically with box model junk) I’ve just done the CSS structure a different way and it works. For example, changing where I use containers, etc. There are high quality elegant solutions to nearly every problem.

    That said, as a last resort in a time crunch…this is a great technique to know!

  • Samer Ziadeh

    I think that technique is too much. I would rather put in another CSS file in the head and have that file conditioned for IE. that way we could save space on the HTML file and won’t have the CSS files cluttered up with different things.

  • Alex

    Otherwise you have nothing better ?

  • http://MeitarMoscovitz.com/ Meitar

    It’s certainly possible that this is too little too late with regards to dealing with IE bugs, though if I’d learned this technique as a CSS newbie rather than the multitude of various (and insanely complex) CSS hacks I’ve used for years, this may have been the method I stuck with in those situations where an IE-only hack was simply necessary. I find it simpler in general and simplicity is generally what I’m after.

  • http://www.tyssendesign.com.au Tyssen

    I wouldn’t go down the route of creating conditional markup for different versions of IE in the HTML, but I did try out this technique just this week as I only came across it the other day too (must’ve seen it in the same place you did ;).

  • http://www.cemerson.co.uk Stormrider

    I don’t like conditional comments at all… I like my HTML to be pristine and leave all the messiness to the CSS! After all, the HTML document is the one containing important semantics, which will be used by far more user agents (screen readers for example) than the CSS.

    I prefer to keep dirty hacks out the HTML.

  • dmwalk

    I see no reason to use this over a simple ie (or ie6, etc.) style sheet with conditional comments in the head. Not only do you have to repeat the conditional markup multiple times in your html, you then have to generate new classes in your css which get mixed in with your non-ie classes. When ie6 goes away, hopefully in another year, you have a mess to clean up in both your html markup and your css stylesheet. I don’t see this making any sense to use.

  • tactics

    I’ve never had to use conditional CSS to get IE7 to behave. In cases where I need to do something different for IE6, I just use the “!important” statement in my external CSS file and that does the trick. I’ll agree with others here that the method suggested here is a bad practice.

  • Serge Krul

    Maybe for a simple web site you can do with one conditional stylesheet, but when you design something bigger you end up with at least four files: (ie6,ie7) x (css,js). The maintenance of such a mess is horrible. The files sometimes reside at different places, and when you edit your main css/js file you can never know what ie mess is hiding somewhere. You need to leave comments in your main css/js. And when something in those conditional files is altered you need to update those comments. A nightmare. This technique saves you a big mess cause you can put all your stuff in one file. Yes, the good browsers will have to download more code. But the extra code is a lot smaller in proportion to the extra maintenance work you need to do.
    I would also like to ask the people above me who do not use any hacks how do they deal with no png, no hover, no max-width in ie6, hasLayout bugs (specifically a.p offsets mess and jumps on hover), 1px round bug, ie’s own z-index model and other peculiarities.
    As for browser sniffing in js, this method is much more reliable than anything else because actually the sniffing is done at the html level by the conditional comments, you only need to check the className of body and execute any needed ie code (like suckerfish menus for example).

  • tactics

    Hi Serge. In answer to your questions:

    1. I don’t use the IE png fix. I rarely use transparent png’s because their file size is larger than gifs. If it is necessary for a particular project, I use a gif for IE, and a png for “real” browsers using the !important declaration in my stylesheet. If you view any of the lightbox popups on classmates.com, you will see an example of where I did that. It just looks a little less fancy on IE6 than it does on other browsers.

    2. The no max-width/max-height thing can be addressed using the “width: expression” hack: http://www.cameronmoll.com/archives/000892.html
    It’s not very elegant, but it works. None of the other issues you mention have ever been a problem for me.

    3. Browser sniffing with js is NOT more reliable. 10% of people have js disabled. And relying on js for your presentation is contrary to the whole concept of separating your functionality from your content and presentation: http://www.sitepoint.com/article/simply-javascript/

  • Serge Krul

    @tactics

    Your answer signifies that you did come across ie’s shortcomings in your development. I also understand from your answer that you used some hacks in your main css file to work around them.
    In this case it’s just a matter of personal preference, not bad/good practice: you prefer to let every browser download all the css, regardless of it’s validity or necessity, and i prefer to use conditional comments to serve the “ugly” stuff only to those who need it.
    However, and this is my point, in some medium-scale projects it can become complex to maintain the conditional files. Therefore the little trick presented here is really nice for such cases, as I mentioned earlier.
    As to your last point, you completely misunderstood me. I never ever wanted to imply that js sniffing is reliable. On the contrary, what i said was that if you use this technique you don’t need to use js sniffing because the so-called sniffing is done at html level by the conditional comments. You’re just checking if the className property of the body element contains the string “ie”.
    For some reason you also decided that i rely on js for presentation while i only mentioned using it for suckerfish menus. I’m always cautious about jumping to conclusions about other people’s code.

  • Arkh

    I discovered this technique in a post on stackoverflow : I love it and started using it. One valid CSS file at the cost of some markup to add in the header and the footer is awesome.