Workarounds and Filters
The art of selectively applying CSS to specific browsers probably began
with the exclusion of Netscape Navigator 4. It was discovered that if you
used a media value of anything except
"screen" on a style sheet link
element, Netscape 4 would ignore the style sheet. At the time, it was
considered safer to avoid attempting to apply CSS to Netscape because it
was so buggy that the CSS was likely to crash the browser.
Not long after that, it was discovered that Netscape didn’t support the
@import at-rule. Simply using @import
url(styles/main.css); achieved the same result and had the added
benefit of excluding all other browsers that provided poor CSS support,
like Internet Explorer 4. Thus the concept of filtering out browsers
through the use of more advanced CSS features gained popularity.
Before you dive into CSS filtering, however, you should take a considered approach to dealing with CSS rendering problems:
Ensure your CSS validates. CSS validation ensures a reliable baseline for dealing with CSS issues. Otherwise, you could waste you time chasing phantoms that turn out merely to be syntax errors.
Check the specifications. Make sure you’re not imagining problems that don’t exist. Some concepts like the box model, positioning, and floats are more complex than people realize, and problems may simply arise from incorrect assumptions about how CSS is supposed to work. This reference is an excellent place to start your research.
Check browser behavior. All browsers have CSS problems of one kind or another. What you’re experiencing may be a rendering quirk or a bug. Researching the reason why the problem is occurring will better enable you to deal with it now and in the future. Web sites like Position Is Everything and the Quirksmode Bug Report are great resources.
Searching for a Workaround
Once you’ve been
through that process, and have confirmed that yours is indeed a
browser-related problem, your next step should be to search for a known
workaround. Many CSS problems can be solved by adjusting your HTML markup
or CSS. For example, a lot of Internet Explorer rendering quirks can be
solved by either enabling or disabling the proprietary
hasLayout property of a given element through the
setting of specific CSS properties—read more about the topic in The Internet Explorer hasLayout Property. Again, the web sites mentioned above, Position Is
Everything and the Quirksmode Bug Report, are a great place to start this
research as they often document usable workarounds for various
problems.
Applying a CSS Filter
If no usable workaround exists for your problem, you may have to resort to applying a different set of rules for a specific browser. You may be able to use a CSS feature that’s not supported by all browsers in order to direct CSS rules to particular browsers—a technique that’s often referred to as using a CSS filter. In doing this, you’re exploiting the feature of CSS error handling that specifies that user agents must ignore statements and declarations they don’t understand.
Using a child selector is another common example of this kind of filtering technique. The child selector is 100% valid CSS—it’s only a filter in the sense that it’s only supported by modern web browsers. Internet Explorer versions prior to 7 have not implemented this feature, so it’s a useful way to hide CSS rules from Internet Explorer 6 and earlier versions. The child selector is commonly used like this:
#test{
position: absolute;
}
html>body #test{
position: fixed;
}
The filter above is designed to address the fact that Internet
Explorer 6 and earlier versions don’t support the value of
fixed for the position property.
These browsers will only set the position of the
#test element to absolute, and will
ignore the second rule. Meanwhile, virtually all other modern browsers
will set #test’s position to
fixed, because they apply the second rule and
overwrite the property.
Though filters can work, you should be wary of rewriting CSS rules for good browsers in order to avoid problems with bad browsers—it just doesn’t seem to be the right thing to do. It’s preferable to target problematic browsers and keep your style sheets uncluttered.
The Star Selector Hack
The star selector hack, also known as the star-HTML hack and the Tan hack, because it was first described in detail by Edwardson Tan, is the most widely used filter; it relies on a peculiar behavior in Internet Explorer 5.5 and 6. Even though it’s often labeled a hack, I’ve included it in this section on filters because, despite the fact that it exploits a browser bug, it uses a valid CSS selector. The selector, however, should never match any elements; all browsers, except Internet Explorer 5.5 and 6, understand this fact and ignore the rule.
The technique is simply to apply a descendant selector that
makes use of the universal selector. The universal selector is, of course,
valid CSS, so don’t be confused and start thinking that using the
universal selector is bad news. The most common form of the technique (and
the origin of its name) is to compose a rule with the *
html selector. This constitutes valid CSS, but it shouldn’t
match any elements. The selector should apply the rule to any
html element that’s the descendant of any other element
and, as html is the root element, it’s never a
descendant of any other element.
However, while most other browsers ignore it, Internet Explorer 5.5 and 6 will interpret this selector as if there was no universal selector, like the rule below:
html {
⋮ declarations
}
Thus, the star selector hack is a safe way of applying CSS rules to Internet Explorer 5.5 and 6 without affecting other browsers.
You’d use it like this:
.test {
position: fixed;
}
* html .test{
position: absolute;
}
Only Internet Explorer 6 and earlier versions will apply the latter rule; other browsers will ignore it.
The three selectors that function in this way are documented in Internet Explorer’s Star HTML Selector Bug.
| Selector | Internet Explorer 5.5/6 Interpretation |
|---|---|
* html |
html |
* * body |
* body |
* html body |
html body |
User-contributed notes
- ID:
- #1
- Date:
- Sun, 10 Feb 2008 09:45:28 GMT
- Status:
- This note has not yet been confirmed for accuracy and relevance.
Table at the bottom of the page needs some tweaking -- none of the values are long enough to warrant wrapping like "* html body" does.
Add a note
To post a note on this topic, please log in with your SitePoint username and password. If you don't have an account yet, you can create a new account for free.
