Cooking with Webstandards! Taste the full flavour of the Web

Filtering CSS

Again this is a post that was inspired by ongoing discussions with students of the IWA HWG CSS workshop. Some of it has been widely covered over the web , but I thought I'd summarize a bit what I found most useful and provide a small link collection.

When it comes to CSS hack's and filters I am the kind of developer that really tries to avoid them. If there is something to be done against minor glitches I tend to use CSS filters and manage the used hacks in several different files that are served to the browsers in question. Most of the main concerns l have with Internet Explorer versions 6, 5.5, 5.0 on Windows (i. e. 1px offset with absolute positioning, initial font size issue with the 5.x branch and the broken box-model.) and Internet Explorer on Mac (for example the miraculous margin-right: 15px added to absolute positioned elements).

So my main strategy is to link to main Stylesheets within my (X)HTML files. A main.css containing the complete hack-free styles (organized probably in the form of further linked style sheets) and a filter.css that contains links to browser specific styles and adjustments.

<link rel="stylesheets" type="text/css" href="main.css" />
<link rel="stylesheets" type="text/css" href="filters.css" />

A schematic illustration showing the file structure described in the next paragraph

Let's have a closer look at the filter.css. It's main purpose is to serve different Styles to Internet Explorers on Windows and Mac.

@import url('ie-win.css'); /*hiding from IE5 Mac*/
  @import "ie-mac.css";

Using single-quotes within the url parentheses of the first declaration hides the imported sheet ie-win.css from Internet Explorer on a Mac. The second rule, the so-called IE/5mac Band Pass Filter is only understood by Internet Explorer 5.x on Mac and therefore a perfect way to fix CSS flaws of this browser and only for this browser.

But wait, the Windows IE styles can still be accessed by all other browsers. That is absolutely right. So let us have a closer look at the ie-win.css. It takes benefit of the "Star HTML Selector Bug". This special selector is only recognized by all versions of Internet Explorer greater or equal to 5.0 no matter what Operating System. But as the stylesheet itself is hidden from IE/Mac, only the Windows versions of Internet Explorer will apply these rules. This is how it looks:

* html body {
   color: #0001A6;

This would set the color of body to blue in Internet Explorer on Windows. If there is a need to adjust furthermore and serve additional styles to IE5.x only (possible scenario: IE6 in standards mode, addressing the broken box-model for IE5.x only), we can use the Mid-Pass Filter to import another stylesheet. The advantage of the Mid-Pass Filter, it is only recognized by Internet Explorer version 5.x :

@media tty {
 i{content:"\";/*" "*/}} @import 'ie5x-win.css'; /*";}
}/* */

Let's look inside the ie5x-win.css, cause there is one important thing to mention:

* html body {
   color: #2EA740 !important;

This rule sets the body color to green in Internet Explorer 5.x on Windows. Why the !important statement here? Well, although the stylesheet for IE5 is imported after the styles for IE6 are written down and specificity of both selectors is the same, the cascading rules tell us that imported styles are treated as if they'd appear at the very beginning of the stylesheet:

Finally, sort by order specified: if two rules have the same weight, origin and specificity, the latter specified wins. Rules in imported style sheets are considered to be before any rules in the style sheet itself.

So the !important statement assures that the IE5 styles won't be overriden by any IE6 styles using the same selector match and specificity.

Check out the testfiles:

Little sidenote

I tried to seperate the styles for IE5 and IE6 on Windows using both the High Pass Filter and the Mid Pass Filter and serving different stylesheets to them in the first place:

@import "null?\"\{";
@import "ie6-win.css";
@import "null?\"\}"; @media tty { i{content:"\";/*" "*/}} @import 'ie5x-win.css'; /*";} }/* */

Unfortunately this didn't work. In this case Internet Explorer 5.5 didn't apply the ie5x-win styles. By reversing the order of the import calls all browsers applied the correct styles, but IE6 only did so when in quirks mode.

So this method leaves at least one browser that is probably not applying the filter under all circumstances which for me equals to useless, no matter how tempting this method is, cause it is the most distinguished one, and you could spare the !important statement for IE5/Win.


I really do not like using CSS hacks, but sometimes you just can't avoid them, at least not if you code for IE. But the above mentioned method is sufficient to me, allows handling of the different hacks in different files, doesn't litter your main stylesheets and is completely valid.


Filter Methods
High Pass Filter
Mid Pass Filter
IE5/Mac Band Pass Filter
Star html Selector Bug
Overview of CSS-only Filters with browser support charts
IE5/Mac specific
Internet Explorer 5 Mac: Oddities - my current number one when it comes to IE/Mac problems. Thanks Philippe
CSS specification
The Cascading order

Posted by Minz Meyer at February 22, 2005, 12:14 PM | To Top

Other ingredients

Nice article. (and nice site by the way)

Yeah, it's pretty nice to have it in seperate files too, because then when the old browsers almost doesn't get used anymore, you can just delete that CSS file before looking through the main CSS file to find the "hack" information for that browser.

Posted by: Andreas Graulund at February 22, 2005 01:23 PM

Die Methode des CSS-Einsatzes, die ich persönlich erstmals bei sah, gefällt mir ausgesprochen gut. :))
Dein Artikel dazu ist sehr anschaulich, gut visualisiert. Gefällt mir und wird mein Sonntags-Link in meinem Sideblog. Danke!

Posted by: Jörg Petermann at March 6, 2005 11:45 PM

It seems a nice, orderly way of handling browser-specific CSS.

Since IE6, and the advent of Firefox, Opera 7.5+ and Safari (that is, all much-used, standards-supporting broswers), I've made the decision to completely ignore IE 5.5 and lower, and adjust for IE/Mac only if the client specifically asks for it. Sometimes I fire up the Mac to see if it looks good in Safari, which it usually does.

As for IE6; I've discovered the very elegant underscore hack: a CSS property preceded by an underscore is invalid CSS, but is still parsed by IE6, and only IE6.

Posted by: Willem at March 25, 2005 11:34 AM

Good article, nice explanations.
A suggestion: why not use the IE - specific Conditional Comments? Then only IE understands what you're trying to tell it, down to build-specific browser versions. Works for me! And I don't need the hacks then!

Posted by: Sebastiaan at May 17, 2005 03:51 PM

good point on the Conditional Comments. I agree with you, that it seems to be one of the best ways to deal with IE insufficiencies.

But, consider the scenario when you are not allowed or have no influence on the HTML markup? This quite often happens when you are designing templates for CMSes or BlogSoftware.

Posted by: Minz Meyer at May 17, 2005 04:32 PM