Conditional comments in CSS

With the advent of Internet Explorer 7 (IE 7), there is now little choice but to create separate style sheets for different browsers, at least for a moderately complex visual design or layout. This post explores the need for change, and where this approach could go. (Skip history, straight to my suggestion.)

The vision

The hope for standards based web developers is that you can simply create an HTML page, apply some CSS for layout and design, and it just works. No hacks, no filters, you use positioning to move elements around, add images via backgrounds etc., and they all work.

Unfortunately this has never happened, ever. Almost the first thing you learn in any CSS tutorial is how to create different rules for different browsers.

Grouping browsers

CSS has some graceful degradation built in, so browsers that do not understand something simply don’t display it. For example, Netscape 4.x doesn’t understand the @import method. IE/Win 5-6 doesn’t understand the child selector. These don’t qualify as ‘hacks’, they are simply a useful way of applying styles that the browser understands, in a way that groups browsers by their CSS support.

Hacking browsers

When CSS support is similar but there is a bug (or at least a conflicting implementation), hacks become necessary. For example, Internet Explorer 5’s implementation of the box-model meant that although it understood the CSS, it displayed it differently to all other browsers.

For more on how CSS hacks developed, I highly recommend Tantek’s article “Pandora‚Äôs Box (Model) of CSS Hacks And Other Good Intentions“. It documents how the main CSS hacks developed, and defines how progress should be made in CSS support.

The upshot for developers was that you would have a style sheet or set of style sheets for standards savvy browsers, and feed less able browsers specific styles to help them round the corners (or whatever you happen to be trying). Usually, it made sense to include these hacks immediately before or after the ‘standard’ rule, within the same file.

IE 6 era

When Internet Explorer 6 (for Windows) came out, it brought with it “strict standards-compliant mode“. I didn’t like it. I appreciated the thought, but it just seemed shaky. Perhaps I’d gotten used to doing layouts with IE 5/5.5, but it seemed easier to group IE/Win 5.0, 5.5 and 6 together. When using XHTML with an XML declaration, you can do just that.

This led to a fairly straightforward set of style sheets:

Basic
Added with the link method, just included fonts, and some basic colours, but no layout or anything that might phase Netscape 4 or (old) phone browsers.
General styles
Using the @import method, these were hidden from browser under version 5.
Print
Using the media attribute on the link, styles to tweak the presentation for print.

General styles is now the issue. It is trying to cover quite a few browsers, from IE/Win 5, 5.5 and 6; to IE/Mac; to Firefox, Safari and Opera.

In general, you can create a layout/design using Firefox, and 9 times out of 10, just check in Safari and Opera and it’s fine. Then add some well know hacks for IE/Win 5-6, and IE/Mac, and it’s there.

Unfortunately IE 7 has broken this blissful, ignorant state. Going back to Tantek’s article on progressing CSS support:

If you support the child selector, now all of a sudden you have to compliantly support all the other properties/values of CSS2(.1) that authors have been successfully using with the child selector.

IE 7 now supports CSS 2.1 selectors like the child selector, and has fixed things like the star-html hack. But it hasn’t fixed all the reasons for using them! On this site for example, there is an IE 7 style sheet because otherwise the header is not centered. It’s a great deal smaller than the IE 6 style sheet, but still necessary.

(NB: I’m not trying to snipe at IE here, I think they are making great progress. Before work seriously started on IE again, I assumed they would have to dump the previous code and start again. I do wish they could have had a little more time to work on the rendering, but at least there is planning for continued progress.)

Filtering For Modern Browsers

If you did find a compatibility problem between Firefox, Safari, or Opera (or worse still, between FF 1.0 and 1.5), what can you do about it?

Um, very little.

Comparing the available filters/hacks across these browsers at Centricle, shows that all these modern browser line up. With the exception of the *7 hack (which is invalid CSS anyway), Firefox 1.5, Safari 2, Opera 8.5 and now IE 7 cannot be differentiated by these methods.

David Shea covers this well, but he isn’t very optimistic about how this will work in future. Will people uncover more hacks to use?

New CSS setup

Trying to get back to ideal standards based development, how should the CSS setup change? Well the first part won’t, but perhaps we can make an addition in future:

Basic
As before, added with the link method, just included fonts.
General styles
Aimed at all modern browsers that understand CSS 2.1.
Print
Using the media attribute on the link, styles to tweak the presentation for print.
Browser specific style sheets, currently:
  • IE 7 style sheet
  • IE 5 – 6 style sheet
  • IE/Mac style sheet

Having just re-done the front-end code on my companies site from scratch with this in mind, it’s working quite well. The CSS imports in the head looks something like this:

<link type="text/css" href="basic.css" rel="stylesheet" />
<style media="all" type="text/css">
   @import url(styles.css);
    /*\*//*/
   @import "macie.css";
   /**/
</style>
<link href="print.css" media="print" type="text/css" rel="stylesheet" />
<!--[if lte IE 6]>
 <link rel="stylesheet" type="text/css" href="ie5-6.css" />
<![endif]-->
<!--[if IE 7]>
  <link rel="stylesheet" type="text/css" href="ie7.css" />
<![endif]-->

This works, for now. Internet Explorer at least provides a method for providing specific styles to specific browsers, but what of the others?

Progressive enhancement

I have run into ‘differences’ and bugs between different versions of Firefox, Opera and Safari. There are also enhancements I would like to target at different browsers, such as David Shea’s text-shadow example, or using items like -moz-border-radius (used on this site), which are not valid CSS.

In order to be able to safely go beyond basic CSS, and deal with inconsistencies, we need a method of targeting different browsers. I’m not sure that this should be part of a standard though, perhaps a conditional-comment style comment mechanism would be best?

Imagine this were the last style sheet imported (example only, I’m not sure if this would conflict with anything else):

/* [if browser Gecko < = rv1.8] @import(ff.css) [endif] */
/* [if browser Safari > 417] @import(safari.css) [endif] */
/* [if browser IE = 8] @import(ie8.css) [endif] */

In common with IE’s conditional comments, the advantages are that:

  • Only browsers that need (or take advantage) of the style sheets will download them;
  • The base style sheets (should) be completely standards based, serving as the foundation (i.e. any new/obscure browser has no excuse if it supports CSS);
  • No validation issues for browser specific code such as IE’s expressions, or untested CSS 3 rules.

Once implemented within the CSS, the HTML pages wouldn’t need style sheets for IE 7.5, 8, 9…

The disadvantages? Well, each browser manufacturer would have to implement this (or something similar) for the approach to work.


Update (2006-06-11)

After writing this, I noticed visits via Google from phrases such as “safari conditional comments”, and so I had a look at what else was there. This brought up Simon Willison’s post on conditional comments (back in early 2003), sparked by Mark Pilgrim and rounded off by Adrian Holvity. I had even commented myself suggesting that Safari should match another browser such as Pheonix (as Firefox was known then), but I can’t find that page any more, even in my site backups :/

Ok, so no new thought here, but there is a new landscape where utility of hacks is decreasing. It seems that Safari’s lead developer is ammenable to the idea.

There was quite a lot of discussion on this over at 456 Berea Street, with some good arguements against the approach in general. There is even one known (valid) IE7 filter, although even the author would still use conditional comments. Most comments were aimed against using browser detection style methods, but really wouldn’t cut it for client work. The only arguement that gave me pause for thought was from Ben ‘Cerbera’ Millard:

When you begin to code a layout, you should test in as many browsers as possible right from the start. Each time you find a non-trivial difference, investigate it methodically to find out its exact cause. You can then try alternative methods of producing the same effect until you find some which work. You can then test each of these methods in other browsers, eventually finding one which works well in them all.

Although fine for personal sites, or when you have a lot of time, there are two reason’s I don’t think this will work in practice:

  1. You will sometimes end up with such a small sub-set of CSS that ‘works’, it will actually be fairly far from an ideal standards based solution. I would rather make the ideal solution, and then add browser specific code.
  2. There are incompatibilities that would mean you can’t do certain things, there is no set of CSS that works for all browsers in some situations. I’ll see if I can pull a couple of test cases together to show that.

Nothing was suggested that would allow a developer to provide clients what they want, and I think Mark’s quote sums it up well:

CSS hiding hacks are evil, but the alternatives are worse.

4 contributions to “Conditional comments in CSS

  1. I was looking for some good practicle advice about IE7, and I discover that you have a personal site Alastair! Hope you’re keeping well, (Stephen @ thAA.com).

  2. Millard\’s methodology seems a bit like a house of cards, a balancing act that requires a number of variables to remain the same for it maintain future functionality.

    Enjoyed you article, thanks…

  3. Thanks Sam,

    I’m slightly embarrassed looking back at my comment from 2003, thinking that it might be easy to replicate another browser’s bugs!

    In truth I don’t think there is a future proof method. Before IE7, I thought that MS would fix the bugs at the same time as the hacks. But it wasn’t quite that easy, the bugs & hacks didn’t quite cancel out.

    Conditional comments became necessary, I’d just like to move them out of the HTML.

Comments are closed.