Peachpit Press

Integrated Web Design: Strategies for Long-Term CSS Hack Management

Date: Jun 25, 2004

Return to the article

Using CSS in a contemporary browser? You'll probably need to use a variety of CSS hacks to accomplish the best possible cross-browser compatibility. Molly Holzschlag helps you determine if you need hacks, how to manage them effectively if so, and which hacks you can employ to solve a range of common compatibility problems.

Hack management? What the heck is that? Well, if you're working with CSS and you're trying to address the oddities of multiple browsers, you simply cannot achieve consistency between those browsers without employing hacks.

So, how is a hack defined? That's another issue up for debate, but for the purposes of this article, a hack occurs any time we use an element, property, or other syntax within a language for a purpose other than its intended application.

Depending upon your site needs, you might be one of the lucky few who never has to employ a CSS hack, but I doubt it (at least for now and at least if you're working with CSS and addressing numerous browser concerns). So, this article will provide you with a variety of hacks as well as offer some incredibly intelligent strategies for managing your hacks and ensuring that they quickly disappear when you don't need a given hack anymore.

After all, we really don't want to use hacks. The biggest hack of all in web design has been the use of tables for layout, and we all know what a mess that's gotten us into.

Hacking Strategies

Before you get hacking, you'll want to know a bit about how to effectively use hacks—or not use them. This section will help you set up your strategy before using a hack.

General Tips

Here are some tips to ensure that you'll manage your hacks with expertise:

/* Box Model Hack to correct Box Model implementations */

After you determine that you will require hacks and are committed to managing them effectively, you're ready for the surgical correction strategy.

Surgical Correction Strategy

This is a strategy I heard Tantek Çelik (perhaps the creator of more CSS hacks known to humankind than anyone) discuss at a recent SXSW panel on CSS. As a developer of browsers as well as a CSS expert, Çelik has had to manage browser inconsistencies with CSS for a long time. Although not a proponent of hacking by choice, Çelik realized that we need to provide options to use CSS as effectively as possible, but removing those hacks as soon as they are no longer needed will enable us to move forward without being encumbered by them.

This strategy makes your hacks easy to manage by placing the CSS syntax in unique files. Then, you can import them into your main style sheet using the @import property. By doing this, you import your hacks into the main CSS rather than actually coding them in the main CSS itself. Let's say you've got a document, hi-pass.css, in which you have the syntax for the hi-pass filter (discussed later in this article). The hack is resident in a file all its own and then imported into the main sheet:

/* importing hi-pass filter */
@import "hi-pass.css";

After you determine that the hack is no longer necessary, you simply delete this syntax from the main sheet, delete the hi-pass.css file, and you are then that much closer to a hack-free environment with very little muss and fuss.

Figure 1 illustrates the surgical connection strategy.

Figure 1Figure 1 Surgical connection strategy

Hacks and Workarounds

Now that you have some good strategies for managing hacks over the long term, it's time to take a look at some popular hacks and workarounds that you may want to use to manage browser issues.

Box Model Hack

As you might know, IE for Windows has incorrect implementation of the Box Model. (The Box Model is a visual model upon which CSS relies to effectively style element boxes.) In the Box Model, each element creates a box that can then be managed using CSS to style its width, height, position, borders, margins, and padding.

Let's say you were to begin with a simple box, such as this one:

#content {
    border: 10px solid black;
    padding: 10px;
    width:300px;
}

In browsers with proper implementation of the Box Model, this would be interpreted by adding the borders and the padding width-wise as follows (you wouldn't add the bottom or top borders and padding because you're concerned only about width in this instance):

Left border 10px +
Right border 10px +
Left padding 10px +
Right padding 10px +
Box width 300px =
340 pixels total width

However, improper box model implementations will place the border and padding inside the width of the box, resulting in those widths being subtracted:

Box width 300px -
Left border 10px -
Right border 10px -
Left padding 10px -
Right padding 10px =
260 pixels total width

No small difference! With this kind of significant discrepancy, you see that some kind of hack or filter is necessary to make sure that your visual layouts are as consistent as possible.

The Box Model hack taps into a parsing bug in those problem browsers to work around the problem. Using the voice-family property, you'll first define the true width, insert the hack, and then apply a width that gets overridden and tricks the problem browsers into using the correct width of 340 pixels:

div.content { 
 width: 340px; 
 voice-family: "\"}\""; 
 voice-family: inherit;
 width: 260px;
} 

Although a feature known as DOCTYPE Switching corrects this problem in IE 6.0, earlier IE versions will misinterpret your CSS badly enough to cause significant layout discrepancies (hence, this hack and later filters that have emerged as alternatives to it). DOCTYPE Switching occurs only when documents are marked up with correct DOCTYPE declarations.

NOTE

Please see "CSS: Beyond the Retrofit" for more information on DOCTYPEs and switching technologies.

Interestingly, using the Box Model hack, CSS would routinely fail the W3C's CSS validator despite the fact that even if it is a hack (again, something being used for a purpose it was not intended) doesn't mean that the syntax has an error. Public commentary encouraged the W3C to correct the validator to support it, so now you can use this hack without worrying about invalid CSS.

Horizontal Centering Hack

Although CSS offers a perfectly acceptable means of centering elements horizontally, browser support of the correct means is inconsistent.

The correct way to horizontally center any element is to use the margin property and set left and right values to auto:

div#content {
    margin-left: auto;
    margin-right: auto;
}

This works in some browsers, but not in others. Another means of centering is to use the text-align property for a given element, which in many browsers will align the element as well as the text:

div#content {
    text-align: center;
}

Because neither the correct way nor the text-align method works in all browsers, you'll want to combine the technique:

div#content {
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}

And this creates your horizontal center hack. Of course, because you now ask that all text be aligned within the element, you'll have to be sure to create rules that overwrite that:

div#content p {
    text-align: left;
}

This makes sure that any paragraph within the now-centered content division will align properly.

@import Workaround

If you are attempting to gracefully degrade your CSS layouts and have to support Netscape 4.x version browsers, you may want to consider using the @import workaround as a solution to ensure that your site degrades the way you want it to.

Netscape 4.x versions have partial support for CSS. Layouts are especially prone to breaking. But, Netscape 4.x version's impartial CSS support is a partial blessing because there's no support for the @import rule. This allows designers to split their CSS into two style sheets:

So let's say you have a site-wide style sheet (styles.css) and a layout style sheet (layout.css), split up in the way described above. You can then link to the styles.css, but import the layout styles using @import:

<!-- begin link to design styles for screen -->
<link rel="stylesheet" type="text/css" media="screen" href="styles.css" />
<!-- begin @import for layout styles -->
<style type="text/css" media="screen">@import "layout.css";</style>

Because Netscape 4.x can read the linked style sheet, some style will be applied to the page. But because it cannot read the @import rule and therefore any styles associated with it, the layout style information is ignored, leaving a more gracefully degraded site.

Filtration Systems

Filters are really just hacks with a fancy name. Specifically, a filter filters out other browsers so you can create a style sheet to hack for a specific browser or browser set only.

High Pass Filter

This filter is a means of filtering CSS rules to a variety of browsers while ensuring that unwanted styles don't get maligned by those problem browsers. The high pass filter takes into account the idea that we want to move toward as hack-free an environment as possible, but still be able to deliver CSS to browsers in some controlled way.

So while we're still hacking away, we're moving those hacks out of the main HTML and CSS documents.

In the case of the high pass filter, you'll first create a linked style sheet with @import rules written to trick browsers without proper implementation:

<link rel="stylesheet" href="highpassfilter.css" />

This style sheet itself contains two rules:

 @import "null?\"\{"; 
 @import "highpass.css";

The first rule is a trick using the same technique in the Box Model Hack to throw off those browsers that can't parse the style value. The second style sheet, highpass.css, will contain your actual styles, which will then be imported into the style sheet and carried over into the compliant browser via the link, leaving the hack separate from the main HTML document and separate from the clean style sheet.

The Mid Pass Filter

This filter allows you to provide a style sheet for versions IE 5.x of Windows without including any other browser. This means you can fix the Box Model and other problems in IE5.x versions without adding those hacks directly to your main documents.

In the case of the mid pass filter, you'll trick the browser using the @media rule with a value of TTY.

Consider the following:

@media tty {
 i{content:"\";/*" "*/}} @import 'midpassbefore.css'; /*";}
}/* */
p.test { color:green; padding:1em }
strong { color:black; background:#fff; padding:0 2px; margin:-2px }
@media tty {
 i{content:"\";/*" "*/}} @import 'midpassafter.css'; /*";}
}/* */

Because of the filtration process based on bugs with the @media rule, both the first and last @media tty rules will be seen only by IE 5.x browsers for Windows and ignored by all other browsers. The style information in the middle will be interpreted by all browsers.

IE 5.0 Windows Band Pass Filter

This filter works on the same premise as the mid pass filter, but is specific to IE 5.0 for Windows only. Every other browser before or after is filtered out:

@media tty {
 i{content:"\";/*" "*/}}; @import 'ie50winbandpassbefore.css'; {;}/*";}
}/* */
p.test { color:green; padding:1em }
strong { color:black; background:#fff; padding:0 2px; margin:-2px }
@media tty {
 i{content:"\";/*" "*/}}; @import 'ie50winbandpassafter.css'; {;}/*";}
}/* */

So in this case, the styles you place in an imported style sheet using the @media tty rule and the associated syntax will be picked up by IE 5.0 only:

i{content:"\";/*" "*/}}; @import 'ie50winbandpassbefore.css'; {;}/*";}
}/* */

Any other CSS in the sheet will be picked up by any browser that supports those styles.

IE 5.5 Windows Band Pass Filter

By now, you have the hang of what these filters are doing, and in this case you're filtering for IE 5.5, specifically. Anything you put into the imported style sheet using the IE 5.5 filtration syntax will be used by IE 5.5 only, with no other browsers able to access that style.

@media tty {
 i{content:"\";/*" "*/}}@m; @import 'ie55winbandpass.css'; /*";}
}/* */

Any additional normal style information within the style sheet will be picked up by those browsers supporting the styles therein, but the styles in the ie55winbandpass.css file is be picked up only by IE 5.5.

NOTE

All the filters in this section were developed by Tantek Çelik and are distributed freely with attribution under a Creative Commons license, http://www.tantek.com/CSS/Examples/.

Hack it Up, Take It Home

If you need to hack, hack away. But doing so using good strategies such as the surgical correction strategy, using only those hacks you truly need, and staying on top of understanding the languages with which we work will make all the difference in the quality and consistency, and ultimately the portability of your CSS-designs.

1301 Sansome Street, San Francisco, CA 94111