Mar 5

a.b.a: cross browser css

I first saw this technique in Jack Slockum’s Ext JS framework.

There are a range of CSS hacks and other types of work arounds available to target the inconsistencies in the various CSS rendering implementations of different browsers; and different browser versions.

A lot of developers I’ve worked with vehemently support the use conditional comments — this is, to insert IE specific stylesheets into a page, to target the various versions of Internet Explorer. Their reasons being:

  • It’s only picked up by Internet Explorer so other browsers don’t have to worry about downloading irrelevant CSS code.
  • You can keep all your different Internet Explorer CSS hacks separate so as you stop supporting versions you can simply remove the offending file and conditional comment code.
  • It’s neater than having all your CSS hacks in the one file.
  • CSS hacks aren’t generally valid CSS and your stylesheet will not validate if you include them in your stylesheets.

Needless to say I tend to disagree with all four of these reasons. My reasons being:

  • What about versions of Firefox, Opera and Safari that need specific hacks in place to get them to display your page correctly? Now you have some hacks in your main stylesheets and others in another file. All your hacks are all over the place, it makes bug fixing a lot more time consuming!
  • Having some styles, in a separate stylesheet, that override styles in your main stylsheet — for a specific browser/ version — makes it harder to see the overall all picture. I have to either remember, or worse, if I am not familiar with the codebase, constantly check the IE specific stylesheet to see if IE specific hacks are in place. It makes developing and debugging a lot more frustrating and time consuming.
  • I now not only have separate stylesheets to worry about, I have to add conditional comments to my templates to make sure they pick that stylesheet up, then manage the stylesheets AND the conditional comments when new versions of a browser come out. Generally this means — for sites with badly designed templates, which, from what I have seen, is a lot — regenerating, retesting and releasing the whole site again. Very time consuming!
  • It’s an extra HTTP request for only IE, especially IE6 which only supports 2 downloads per domain, and probably for only a small amount of extra CSS code.
  • IE is probably your biggest market share and you’re punishing them with this extra download.
  • It’s easier to see what’s going on when you have all your hacks for each browser grouped together rather than scattered all over the place.
  • How many users care whether or not your CSS validates? Chances are it’s going to be less than a percent of them.

A Better Approach

I’ve used Ext JS on a few big “single page application” projects over the past 4 years. It’s an amazing framework, In my opinion, it’s probably the best and most complete — inlcuding documentation and samples — JavaScript UI framework on the market, at the moment.

One of the first things I wanted to know was: how does it get it’s UI components to look the same in all supported browsers?

It definitely doesn’t use conditional comments because you only need to include one stylesheet and one JavaScript file if you want to use everything Ext has to offer. I started looking at its stylesheets to see if I could find any hacks, none.

What I did find were styles like:

.ext-ie6 .x-form-text, .ext-ie7 .x-form-text {...

In case you can’t tell, this specific rule is targetting IE’s versions 6 & 7.

So I looked at the Ext JS API doc’s generated markup in Firebug and saw this:

<body class="ext-gecko ext-gecko3 ext-mac"/>

And in Safari’s debugger, this:

<body class="ext-safari ext-mac"/>

In case you can’t guess, these classes were added to the body tag via JavaScript.

To me this is a brilliant idea! So brilliant I have used it on other projects to make it easy for all developers to write cross browser CSS. I will also be using this approach in the thudjs framework for the same reasons.

But this will only work with JavaScript turned on…

All I can say to that is, “So?”. How many of your users are actually using your site WITHOUT JavaScript turned on? Do you actually test your site(s) without JavaScript turned on, in every browser? Chances are you’re either living in a fantasy world or your site is so simple you don’t require any hacks or cross browser CSS.

This technique still conforms to the principles of graceful degredation/ progressive enhancement. You’re site may look a little b0rked to 0.001% of your users, if that. It does not mean that this miniscule percentage of users will not be able to navigate your site.

This is the technique you want to use if you want to make your CSS easier to maintain and reduce your overall development/ bug fixing time.

Imagine opening a CSS file and seeing code similar to this:

#container { background-position : left top ; background-repeat : no-repeat ; width : 100px ; }
.gecko  #container { background-image : url(firefox.png) ; height : 97px ; }
.ie     #container { height : 94px ; }
.ie6    #container { background-image : url(msie6.png) ; }
.ie7    #container { background-image : url(msie7.png) ; }
.ie8    #container { background-image : url(msie8.png) ; }
.safari #container { background-image : url(safari.png) ; height : 88px ; }
.chrome #container { background-image : url(chrome) ; height : 104px ; }

Now to me, that is an easy to read snippet of CSS. Rather than having to waste time looking for hacks or sifting through different files looking for the correct rule(s) to change. I can see the main rule and what browsers/ versions required adjustments. If there are any bugs raised with specific browsers/ versions I can make quick adjustments. If a new browser version comes out that fixes a previous CSS rendering bug or updates its CSS3 support, I can take care of it in a matter of a few minutes.

Your choice…

If your interested in this approach to cross browser CSS, I have created a standalone script available for download (less than 1kb gzipped). It creates a global object called UserAgent which you could very easily change to sit under your own namespace. There’s also a test page to display all the values contained in the UserAgent object, the classes assigned to the page’s documentElement (HTML tag) and an approximation of how long it took to complete the operation, for anyone interested in how this script will affect page speed — it’s generally less than 5ms.

However, if you get your kicks from making things difficult for yourself, well then there are, as we’ve seen, a few choices at your disposal. :^)


  1. thudjs posted this
Page 1 of 1