Friday, September 26th, 2008

Maintaining Browser Specific CSS

Category: CSS, Tip

<p>Nick Cairns saw our post on conditional CSS for browsers and followed up discussing how he handles maintaining IE specific CSS selectors:

We keep our IE related styling right below the common (standards-based) declarations. BUT, we DON’T use hacks. Underscore hacks, * hacks, and all of those things that we all gave up with the birth of IE7 should remain dead and buried. Instead, we’re going to use IE’s conditional commenting to create IE specific CSS selectors. We do this by adding a conditional comment block as the outer most wrapper in our html template (ie. the first tag inside the ).

  1. </body><body>
  2.      <!--[if IE 7]><div id="body1" class="IE IE7 IE67">< ![endif]-->
  3.      <!--[if IE 6]><div id="body1" class="IE IE6 IE56 IE67">< ![endif]-->
  4.      <!--[if IE 5]><div id="body1" class="IE IE5 IE56">< ![endif]-->
  5.      <!--[if !IE]>-->
  6.           <div id="body1" class="W3C">
  7.      <!--<![endif]-->
  8.                 /* THE REST OF YOUR HTML GOES HERE */
  9.           </div>  
  10.   </div></div></div></body>

Now, in this sample, we do have support for older legacy versions of IE, so you could always reduce the number of conditions if your project doesn’t need this level of support. And, you could also easily extend it to include IE8, or to do minus versioning such as IE8-.

With this conditional block in place, it becomes quite easy to place IE only style declarations right below their standards-based counterparts. As an example:

  1. #header { overflow: hidden; }
  2. .IE #header { zoom: 1; }

Related Content:

20 Comments »

Comments feed TrackBack URI

Good god, how messy would that make your templates.

How about simply using conditional comments to load in an i.e. 6 only style sheet which you over ride your styles with i.e. ones.

Its what we do, and its easy and maintainable.

Comment by johnwards — September 26, 2008

I prefer putting the a class on the body tag, corresponding to the browser type, like – technique detailed here: http://www.eribium.org/blog/?p=173

Comment by maccman — September 26, 2008

No.

Conditional comments around your CSS links/imports has the direct advantage of not downloading a whole bunch of un-needed stylesheets.

Comment by AdamB — September 26, 2008

ajaxian doesnt work :s

Comment by sharkooon — September 26, 2008

This is similar to the article on Position is Everything: http://www.positioniseverything.net/articles/cc-plus.html

Comment by dave1010 — September 26, 2008

Amazes me that after all these standards, all this teaching, we still have people who think that “This page is best viewed in [NOT YOUR BROWSER]” is a good idea.

Personally, I still use the underscore hack for IE6. It works and keeps the IE-only styles alongside the styles for other browsers. That’s another benefit with the above solution over using separate CSS files. Cuts down on HTTP requests and keeps related styles together.

Used a similar trick before, but with the body element rather than divs.

Comment by jaffathecake — September 26, 2008

Well if they have only single base html template and use extensions/inheriting/including of this template then it’s not so messy. It’s only one place with couple of lines. For me it looks like nice solution, I personally use conditions to load iesucks.css stylesheet for IE6,7 ;)

Comment by naos — September 26, 2008

I agree with maccman, I think the link he posted might be a better approach. But, there are a couple of different approaches:

1. Conditional Comments (this technique): IE only, should Firefox have conditional comments?
2. Using JavaScript to parse the user agent on the client to add a parent CSS Class: what if a user has JavaScript disabled or is a mobile browser that doesn’t support JavaScript?
3. Using a Server side view helper to parse the user agent and add a parent CSS Class (in maccman’s link): the most robust solution, in my opinion.

Comment by zachleat — September 26, 2008

I really don’t understand what this method nets over using IE conditional comments to selectively include style sheets. Basically load a general one, and then load one browser specific style sheet. It will probably result in LESS css on the wire, as you wont have your one file cluttered with tons of IE garbage served to Firefox browsers.

Comment by jonhartmann — September 26, 2008

This is a terrible 1990s style approach and in my opinion it violates the separation of content rule. Everything within the body tags of a page should be strictly content. That means no conditionals, no inline JavaScript or CSS declarations, etc. Additionally, you’re including the extra css information in your style sheet for everyone, not just IE users. I don’t know about you, but it drives me crazy. The best practice is to include your standard style sheet(s), then use conditional comments (in the HEAD) to include additional style sheets with fixes for IE. The fixes won’t be browser specific CSS classes, but overwrites for css styles already defined in your main css.

Comment by mjuhl — September 26, 2008

The cleanest, most efficient way is to wrap link elements, that call stylesheets for specific versions of IE, in conditional comments in the head. Non-semantic markup in the body should be avoided whenever possible.

Comment by WillPeavy — September 26, 2008

Everyone railing against this issue is assuming one thing: that the developer(s) in question have complete control over every part of the website they’re building. This isn’t always the case. Where I work, the client has essentially demanded that whenever we work on new elements of their (very large, highly-trafficked, international) site, all changes/additions/etc. go in one “Master” stylesheet. We hate it, but it’s a requirement. Conditionally-commented link tags or import statements are not an option.

This method is going to be a godsend for us, in our situation where we have control over the HTML, but not over other business requirements (logical or otherwise) of the client.

Comment by spaulo — September 26, 2008

The first code block above has some extra tags, so you may want to click through to the link (or remove the tags that appear to be duplicates) to see my original sample. With that said, I’m trying to illustrate an approach that makes CSS maintenance and peformance at the top of the stack. If you’re build a large scale web application, keeping an IE only stylesheet can be a real hassle and add to debugging time (especially if you have multiple people working on the CSS). To add, with IE still in the majority, adding yet another http request to a page is far more damaging than including the IE specific styles for all. If you are able to build in a more sophisticated deployment process, you can circumvent this at that point, but I still find maintenance a real headache.

Comment by NICCAI — September 26, 2008

@spaulo: If you must contain everything in one style sheet, you could use the * override for IE6:

#body1 { } /* standard styles */
* html #body1 { } /* ie6 fixes */

Furthermore, if you can use javascript you could do something like this:

// example for IE 7
if (document.all && !window.opera && window.XMLHttpRequest) {
document.getElementsByTagName(“body”)[0].className = “ie7″;
}

Then, define your styles like this:
body.ie7 #body1 { }

Comment by mjuhl — September 26, 2008

I find that conditional comments make version of IE download a separate works best, especially for sites that I create and I am the only developer. For my day job, where we have several developers, hundreds of pages this does not work well at all. Sometimes using _ (underscore) hack works best. No extra style sheets at all. We have a rule that whenever you use an IE specific hack you have to comment it a specific way. We had a developer that just hated the fact that we never used conditional comments, but she came from a small design agency where there was just one developer per project and they were creating the sites from scratch. In the real world this doesn’t happen very often.

We also built a script that builds IE specific style sheets based on previous “hacks.” It goes through and makes a stylesheet based on the only _ hacked rules.

Comment by howardrauscher — September 26, 2008

Nice approach Nick, sometimes people on Ajaxian are so in love with the idea of standards compliance that the realities of every day workflow are never considered. Moreover many of them don’t consider the ramifications of splitting style sheets in large scale sites. Many developers such as myself have inherited code or even utilized code options listed here and they were less effective. A short list of why Nick’s technique is probably optimal.

1) Conditional stylesheets are not an effective method of maintaining large scale sites because its a nuisance to find the correct style, file caching systems require that the upload/delivery workflow is extended whereby your architecture needs to be quite need for renaming all includes, and for the aforementioned, the added hit for downloading an extra file.

2) This is obvious but the hacks mentioned above are horrible, why bother, everytime a new browser comes out you’ll have to test like there is no tomorrow. Conditional statements are stable, clean, and reliable; the method of their use is all that is relevant here.

Anyways kudos to you Nick. I may just adopt something similar.

Cheers,
Owen

Comment by OwenL — September 26, 2008

1. The markup shown on Ajaxian was currupted.
2. A comment on the original post shows the more practical (slightly) simplified markup.

Reasons I think this might be great: Valid HTML, lighter-weight than conditionals around LINKs, more reliable than UA sniffing, AND keeps related styles in close proximity.

Comment by Steve Clay — September 26, 2008

I am ashamed to see an example like this on ajaxian. This is not adhereing to web standards in ANY way. Yes, using conditional comments is good when you absolutly need to, but the example above produces a whole lot of mess that leasds to nothing.

Normally you only need conditional comments when there is absolutly no other way, which would result in only small extra stylesheets, not ladden with tons of extra code.

We are trying to push forward the use of web standards and how we build HTML and use CSS to be more effecient with our code and then we examples like this are offered. I think Ajaxian is read by a lot of people and if this is put forward as best practice than we can just bury our efforts to improve readability and maintainability of our HTML templates and go back to drawing table layouts.

So what rules should you follow? Your HTML structure should look the same, no matter which browser is served. If you really really need too, if you will not have to do, if you have done your (X)HTML/CSS homework, then you can add extra information for IE through conditional comments or hacks, though both should be discouraged. Keep you HTML structure clean and without any sight of browser specific tags, otherwise this will end in a total maintenance nightmare!

Comment by Melianor — September 28, 2008

This is obviously a bit of an edge case, but some network appliances can strip out conditional comments in an effort to reduce the amount of data being transmitted (thinking the conditional comments are just normal HTML comments).

Comment by waltr — September 28, 2008

Wow this is crap! It definitely makes your templates unreadable.
Not only that but it is hell to maintain it.
To me it looks like a bad example.
What if you use conditional comments to create you own stylesheet for ie only?

This has some advantages:
1. Your main stylesheet remains small
2. Your templates stay the same for all browsers. This saves soo much time doing redesign of the site of certain elements.
3. It is much more maintainable.

Comment by xfinx — September 29, 2008

Leave a comment

You must be logged in to post a comment.