Conditional Comments Considered More of a Hack Than CSS Hacks

22 June 2007

Many web developers these days eschew CSS filters in favor of conditional comments in their HTML pages. At least in part because the vendor producing pretty much the only browser these days that requires the use of this kind of brute force design technique has asked us all to stop using CSS “hacks”.

I don't agree, thus this post.

The Problem With CSS Hacks

There are obviously problems with CSS filters. To recap, CSS filters use known bugs or limitations in a browsers´ CSS implementation to hide or alter rendering rules for some elements of a web page. The problem here is that you can't target the specific problem you're trying to workaround. Instead, you depend on the bug which causes the filter to be applied to not go away before the buggy behavior you're trying to work around with the filter is fixed.

For example, the box model hack works pretty much perfectly. It's only needed for versions of IE prior to 6.0, and for IE6 Microsoft fixed the box model and the bug in the CSS parser, so that the filter only kicks in for older IE versions. (Well, there were problems with some old versions of Opera which required adding the "be nice to Opera 5" hack, but let's ignore that.) We're not always that lucky, of course, and sometimes a filter will no longer be applied even though the behavior it works around has not been changed. You clearly need to choose your hacks wisely. That's what the IE teams “Call to action” was basically about.

Conditional Comments Are No Better

The IE team went on to suggest using conditional comments instead. Personally, I think that's almost always a step in the wrong direction, for a number of reasons.

Let's look into the example they provided: the freshly modernized Slashdot design was using a CSS filter that applied a negative top margin to a certain fieldset, because they were using an empty <legend> in that fieldset to quiet the validator, and IE, ever since adding support for fieldset legends, reserves some space for the legend even if it is empty. Sheesh, don't let validation errors make you add stupid workarounds that you have to work around in some other place. But anyway…

The IE team suggested Slashdot should have used something like the following instead:

  <!--[if IE]>
      #footer .search {
        margin-top: -1.6em;

That may look like a reasonable approach, until you consider that in some future version of IE, the developers might decide to fix the current behavior of reserving space for empty legends. Which, let's be honest, was a really bad idea in the first place—almost on par with the stupidity of adding a non-resettable padding to all form buttons (see page 18).

So at that point you'll have to go into that HTML markup and add a version check to the condition. That is no better than if you had to adjust your filter for IE7, in my opinion.

Conditional Comments May Even Be Worse

In addition to not having solved the problem with CSS hacks by moving to conditional comments, you are adding a couple of new problems.

For starters, because the conditions need to be in your HTML markup, you are moving the hacks far away from the default rules, probably into a separate CSS files. So every time you try to debug why IE renders as it does, you'll need to look check whether you're overriding any of the default rules in your IE-specific CSS file(s). And, truth be told, the IE developer toolbar is simply too primitive to be of any help here. In contrast, CSS hacks are traditionally placed in close proximity to the default rules, making them a lot easier to locate and understand.

But more importantly, only IE actually looks inside conditional comments. They are comments after all, which user agents and intermediaries can basically dismiss as having no relevance whatsoever. But in IE, depending on whether the condition is met or not, the content of the comment may actually be treated as markup just as the rest of the page is.

The consequences are subtle but problematic. Consider a tool such as mod_proxy_html, which parses your HTML, and rewrites any internal links so that they use the correct path. mod_proxy_html will not look into the markup you've tucked away into comments, so any links you have inside them are not rewritten and will be broken.

This is even more of a concern if you're using an XML-based tool chain to generate your HTML pages. XML processing tools will usually not look into comments at all. If you use XML templating (for example Genshi), the template engine will not try to peek inside your comments and substitute variables, apply conditional processing or perform loops, because, well, they are just comments and passed through as-is, or even stripped out completely.

Using conditional comments would require such tools to attempt to handle the magic IE syntax, and process the content of comments accordingly. Kid has tried to add some support for conditional comment processing, without really reaching a satisfactory solution.

“*+html” is the new “* html”

My recommendation is to try to avoid conditional comments. They don't really solve the problem with CSS hacks, and on the other hand introduce additional problems that may be even more severe.