Band pass filters
Tantek Çelik created a series of filters (http://tantek.com/CSS/Examples/) based on
browser parsing errors that allow you to supply stylesheets to selected browsers using the
@import rule. Because this is a CSS rule, all of these filters can live in a single CSS file,
allowing all your filtered files to be controlled from one place. Separating your hacks into
browser-specific CSS files can greatly simplify your hack management. If you decide to
remove support for a specific browser, such as IE 5.0, you can simply remove the associated
stylesheet, rather than having to trawl through lines of code.
To pass a CSS file to IE 5 and 5.5 on Windows, you can use Tantek’s mid-pass filter:
@media tty {
i{content:"\";/*" "*/}} @import 'ie5x.css'; /*";}
}/* */
This filter looks like a jumble of meaningless rules, and to many browsers that is exactly
what it is. Browsers only capable of understanding CSS 1 will not recognize the @media rule
and completely ignore it. More capable browsers will see a single declaration inside the
@media rule, targeting the <i> element. Due to the existence of an escape character present
before the second quote mark, the value of the content property is treated as a single
string of meaningless characters. Essentially, modern browsers will see a rule that looks like
this:
@media tty {
i {
content:"Blah, blah blah";
}
}
The tty media type refers to terminals and teletype machines. Fortunately, no devices currently
support this media type, so the whole rule is effectively ignored by compliant
browsers.
However, IE 5.x/Win doesn’t honor the escape character, and closes the content declaration
prematurely. The following characters close both the <i> and @media rules, causing
the @import rule to be applied. Any superfluous characters are commented out, and the
whole rule looks like this to IE 5.x/Win:
@media tty {
i{
An escape character is a reserved character—usually a backslash—that causes
the following reserved character to be ignored by the parser. So if you wanted to
auto-generate a quote mark using the CSS content property, you would have to
escape it, or it would prematurely close the open quote:
blockquote:before {content: "\""}
CSS MASTERY: ADVANCED WEB STANDARDS SOLUTIONS
158
content:"blah";
/* blah */
}
}
@import 'ie5x.css';
/* blah */
This is all quite complicated, so luckily you don’t need to know how these filters work; you
just need to know how to use them.
In order to target a particular version of IE 5.x/Win, two variations of the mid-pass filter
were created that exploited various bugs in those particular browsers. These were called
the IE 5/Windows band pass filter:
@media tty {
i{content:"\";/*" "*/}}; @import 'ie50win.css'; {;}/*";}
}/* */
and the IE 5.5/Windows band pass filter:
@media tty {
i{content:"\";/*" "*/}}@m; @import 'ie55win.css'; /*";}
}/* */
The other browser you may want to explicitly target is IE 5.2 on the Mac. You can do this
using Tantek’s IE 5/Mac band pass filter, which exploits a different escaping bug, this time
within comments:
/*\*//*/
@import "ie5mac.css";
/**/
IE 5/Mac incorrectly escapes the second asterisk, causing the @import rule to be applied.
As such, IE 5/Mac sees something like this:
/* blah */
@import "ie5mac.css";
/**/
All other browsers correctly ignore the escaping element, as it is enclosed within a comment,
and the @import rule is commented out. Essentially, all other browsers see a rule
that looks like this:
/* blah *//*
blah
*/
As with the other band pass filters, it is not necessary to understand how this filter works
in order to use it. The beauty of these filters is they specifically target bugs in older, outof-
date browsers. Therefore, you should be able to use these filters safe in the knowledge
that they shouldn’t cause problems in newer browsers.
Filtering individual rules and declarations
If your CSS files are small and you only need to employ a few hacks, you can choose to add
the associated filters into your main stylesheets. However, remember that all these rules
and declaration-specific filters do add extra weight and complexity to your code.
The child selector hack
The safest filters rely on unimplemented CSS rather than browser bugs. As these filters use
valid CSS selectors to apply valid declarations, they are not, strictly speaking, filters at all.
They are simply valid CSS rules that certain browsers fail to understand. The first of these
filters is known as the child selector hack. IE 6 and below on Windows does not support
the child selector, so you can use it to hide rules from those browsers. For this filter to
work, you must make sure that there is no whitespace before or after the child selector.
In this example, the child selector hack is being used to hide a transparent background
PNG image from IE 5-6/Win:
html>body {
background-image: url(bg.png);
}
IE 7 is expected to support the child selector. It is also expected to support native PNG
transparency. By using the child selector filter in this way, you are building in forward compatibility
by allowing newer versions of IE to view the transparent background without
needing to revisit the code.
Attribute selector hack
Another interesting way to filter rules is by using the attribute selector. Many modern
browsers such as Safari and Firefox support the attribute selector, but it is not supported
by IE 6 and below. As such, you can use the attribute selector as a way of styling classes
and IDs for more advanced browsers. In this example, the attribute selector is being used
to apply a background PNG to the content div on more compliant browsers:
div[id="content"] {
background-image: url(bg.png);
}
Again, both the attribute selector and PNG alpha transparency support are scheduled for
IE 7, which means this method should work seamlessly when IE 7 launches.
This method can be used in some very creative ways. For instance, Andy Clarke used
this technique to create two completely different themes for his personal site,
www.allthatmalarkey.co.uk. More advanced browsers get a nice, high-definition
color theme (see Figure 8-2), while less capable browsers get a retro two-tone theme (see
Figure 8-3).
The star HTML hack
One of the best-known and possibly most useful CSS filters is known as the star HTML
hack. This filter is incredibly easy to remember and targets IE 6 and below. As you are
aware, the HTML element is supposed to be the first, or root, element on a web page.
However, all current versions of IE have an anonymous root element wrapping around the
HTML element. By using the universal selector, you can target an HTML element enclosed
inside another element. Because this only happens in IE 6 and below, you can apply specific
rules to these browsers:
* html {
font-size: small;
}
Adding a universal selector followed by an html type selector to the start of any regular
CSS rule will hide that rule from everything other than IE. The most common way to use
this filter is to set a rule that you want all browsers other than IE to apply, and then override
that rule in IE using the star HTML hack. For example, IE renders 1-pixel dotted lines
as ugly dashed lines by mistake. To avoid these ugly dashed lines, you could set the hover
border style on your anchors to dotted but override this in IE, making them solid instead:
a:hover {
border: 1px dotted black;
}
* html a:hover {
border-style: solid;
}
It is very unlikely that this bug will appear other browsers, and it is expected to be fixed
in IE 7. Therefore, the star HTML hack provides a relatively safe way of targeting IE 6
and below.
IE/Mac commented backslash hack
Another useful filter is known as the commented backslash hack. IE 5 on the Mac incorrectly
allows escaping inside comments, so this filter works by adding a backslash in front
of the closing comment identifier. All other browsers will ignore this escape and apply the
following rules. However, IE 5/Mac will think that the comment is still open, ignoring
everything until the next close comment string.
/* Hiding from IE5/Mac \*/
#nav a {
width: 5em;
}
/* End Hack */
This bug forms the basis of the IE 5/Mac band pass filter you saw earlier.
CSS MASTERY: ADVANCED WEB STANDARDS SOLUTIONS
162
If you combine the star HTML and commented backslash filters, you get the Holly hack,
named after its inventor, Holly Bergevin. By combining these two rules, it is possible to
apply rules to IE 6 and below on Windows:
/* Hiding from IE5/Mac \*/
* html {
height: 1px;
}
/* End Hack */
This can be very useful for attacking and fixing all kinds of Windows-specific IE bugs, and
is possibly one of the most used filters around.
“Big John” and Holly Bergevin run www.positioniseverything.net, the definitive
resource on browser bugs and workarounds. Together they discovered or
documented many of the hacks and bugs seen in this and the following chapter.
The escaped property hack
IE 5.x on Windows ignores escape characters. This bug forms the basis of the mid-pass filter
you learned about earlier. It also forms the basis of the much easier escaped property
filter. As the name suggests, this filter works by adding an escape character within a property.
All modern browsers should ignore this escape character, but IE 5.x/Win thinks this is
part of the property name and, not recognizing the property, ignores the declaration.
#content {
w\idth: 100px
}
As such, the escaped property filter provides a simple way of hiding styles from IE 5.x/Win.
However, you need to be careful when using this filter as the backslash character cannot
come before the numbers 0 to 9 or the letters a to f (or A to F). This is because these values
are used in hex notation and may therefore get escaped.
Tantek’s box model hack
Tantek’s box model hack was one of the first CSS filters ever invented. Tantek Çelik created
this filter at the behest of Jeffrey Zeldman to allow him to work around IE’s proprietary
box model (see Chapter 9). This filter works by passing one width to IE 5 on Windows and
another width to all other browsers. It does this using the same escape character bug used
in the band pass filters:
div.content {
width:400px;
voice-family: "\"}\"";
voice-family:inherit;
width:300px;
}
“Big John” and Holly Bergevin run www.positioniseverything.net, the definitive
resource on browser bugs and workarounds. Together they discovered or
documented many of the hacks and bugs seen in this and the following chapter.
Unfortunately, Opera 5 has the same parsing bug as IE 5.x/Win. As such, a second rule is
required to give Opera the correct width:
html>body .content {
width:300px;
}
If it weren’t for this filter, pure CSS layout may never have been possible. However, these
days it is seen as an ugly and complicated filter, best avoided. I have included it in here
purely for its historical significance and because you will still see it being used in older
stylesheets. These days, it is much more common to use the modified simplified box
model hack.
For more on the history of this, and several other filters, see Tantek Çelik’s excellent
article, “Pandora's Box (Model) of CSS Hacks and Other Good Intentions,”
at http://tantek.com/log/2005/11.html.
The modified simplified box model hack
The escaped property hack can be combined with the star HTML hack to create the modified
simplified box model hack, or MSBMH for short. This hack is used for working around
IE’s proprietary box model by providing one length value to IE 5.x/Win and then the correct
length value to IE 6/Win and all other browsers:
* html #content {
width: 80px;
w\idth: 100px;
}
html #content {
width: 100px;
padding: 10px;
}
The modified simplified box model hack is easier to remember and much cleaner than
Tantek’s box model hack, and so is currently the preferred box model hack. This filter can
be used for more than just box model hacks, so don’t let the name limit you.
The !important and underscore hacks
There may be some instances where you wish to apply one declaration to IE 6 and below on
Windows and another to all other browsers, within the same rule. To do this, you could use
the commented property hack, or you could use the !important or the underscore hack.
For more on the history of this, and several other filters, see Tantek Çelik’s excellent
article, “Pandora's Box (Model) of CSS Hacks and Other Good Intentions,”
at http://tantek.com/log/2005/11.html.
The !important hack works because IE 6 and below on Windows has problems dealing
with multiple properties in a single rule:
#nav {
position: fixed !important;
position: static;
}
IE 4-6/Win will ignore the first declaration and apply the second. All other browsers will
apply the first declaration because it is using the !important keyword, which increases the
rule’s priority within the cascade (see Chapter 1).
Similar to the !important hack is the underscore hack. By placing an underscore in front
of a property, compliant browsers will no longer recognize that property and the declaration
will be ignored. However, IE 6 and below on Windows ignores the underscore and
thus applies the rule. So in this example, all modern browsers will apply a position of
fixed, skipping the unknown second rule. IE 4-6/Win will ignore the underscore and will
override the first rule, setting the position to static.
#nav {
position: fixed;
_position: static;
}
The Owen hack
All of the filters so far have been aimed at various versions of IE. This is partly because IE
has more bugs than most current browsers. However, it is also because IE is by far the most
prevalent browser, so more bugs get found and documented. But there are other buggy
browsers out there, including Opera 6 and below.
The Owen hack allows authors to hide styles from Opera 6 and below, as well as from IE 6
and below on Windows. This filter works because these browsers do not implement the
first-child selector. Because there can only ever be one head element, it is always a firstchild.
The body tag always comes after the head tag, and so can be targeted using an adjacent
sibling selector. The resulting selector is understood by more compliant browsers,
while being ignored by version 6 and below of Opera and IE on Windows.
In the following example, the Owen hack is being used to add a background PNG image on
the body tag for more compliant browsers, hiding it from IE/Win and Opera, versions 6
and below:
head:first-child+body {
background-image: url("bg.png");
}
If you only want to target Opera 6 and below, you need to combine the Owen hack with
the child selector hack. Say you wanted to display an upgrade notice to Opera 6 users. You
would first use the child selector hack to show your upgrade message to every browser
except IE 6 and below on Windows. You could then use the Owen hack to hide the message
from more modern browsers:
html>body #getFirefox {
display: static;
}
head:first-child+body #getFirefox {
display: none;
}
Summary
In this chapter you have learned that hacks and filters can be an important weapon in any
CSS developer’s arsenal. However, hacks need to be used sparingly, and preferably as a last
resort. If you do need to use hacks or filters, do so with forward compatibility and ease of
maintenance in mind.
Copyright © 2009-2010 分享前端开发技术博文、工作心得,技术交流
Gtalk: agikoo@gmail.com QQ交流群: 101232616
http://uecode.com/

浙公网安备 33010602011771号