Mostly practical advices

CSS hacks and filters

In an ideal world, properly coded CSS would work in every browser with CSS support. Unfortunately, we do not live in an ideal world, and browsers are littered with bugs and inconsistencies. To create pages that displayed the same across a variety of browsers, CSS developers had to get creative. By using bugs and unimplemented CSS, developers were able to selectively apply different rules to different browsers. Hacks and filters are a powerful weapon in a CSS developer’s arsenal. However, with great power comes great responsibility. It is important to know about the various common hacks and how they work, but it is equally important to know when and when not to use them.

An introduction to hacks and filters

A CSS filter is a way of displaying or hiding rules or declarations from a particular browser or group of browsers. Filters rely on weaknesses in a browser such as parsing bugs and unimplemented or incorrectly implemented CSS to show or hide rules from that browser.

A CSS hack is simply an ugly and inelegant way of getting a browser to behave the way you want it to. CSS hacks are typically used to get around specific browser bugs such as IE’s proprietary box model. Unfortunately, the term hack has rather negative connotations and implies that there is a better way of doing something when often there isn’t. Therefore, some people favor the term patch to indicate that it is actually incorrect browser behavior that is being dealt with.

CSS hacks can use filters to apply one rule to one browser and a different rule to another. Alternatively, hacks can use incorrect CSS implementation to “trick” browsers into behaving the way you want them to. In essence, a CSS filter is a specific type of hack used for filtering different browsers. Unfortunately, most people tend to use the generic term hack to describe filters. As such, when people talk about CSS hacks, they are usually talking specifically about filters.

A warning about hacks and filters

As a language, CSS was designed to be very forward compatible. If a browser doesn’t understand a particular selector, it will ignore the whole rule. Likewise, if it doesn’t understand a particular property or value, it will ignore the whole declaration. This feature means that the addition of new selectors, properties, and values should have no adverse effect on older browsers.

You can use this feature to supply rules and declarations to more advanced browsers, safe in the knowledge that older browsers will degrade gracefully. When a new version of the browser is launched, if it now supports the CSS you were using as a filter, it should work as expected. If you are using the more advanced CSS to circumvent a problem in the older browsers, hopefully this problem will have been solved in the newer version. Because of this behavior, the use of unsupported CSS as a filtering mechanism is a relatively safe option. I say relatively because there is always a chance that the browser will support your new CSS but still exhibit the bug you were trying to fix.

Using filters that rely on parsing bugs is a slightly more dangerous route. This is because you are relying on a bug, not a feature. Similar to the previous method, if the parsing bug gets fixed but the bug you are trying to fix hasn’t been addressed, you could end up with problems. However, more of a concern is that parsing bugs could find their way into newer versions of browsers. Say, for instance, a new version of Firefox has a particular parsing bug. If that bug is being used as a filter to supply IE with different width values to account for its proprietary box model, all of a sudden Firefox would inherit that width, potentially breaking a lot of sites.

It is also worth bearing in mind that some hacks and filters will invalidate your code. For instance, using a CSS 3 selector will fail the validator as it currently only validates against the CSS 2 spec. However, if several browsers support the selector, there is a good chance it will make it into the final specification. In situations like these, as long as you know that you are using valid CSS 3, the fact that your CSS fails to validate to CSS 2 probably is not a big deal. More worrisome are hacks that use illegal characters as they have the potential for causing all kinds of parsing errors in future, yet-to-be-developed browsers.

As a general rule, it is probably safer to use filters that rely on unsupported CSS, rather than ones that use some kind of browser bug.

Using hacks sensibly

There is a rather unfortunate overreliance on hacks and filters, especially among those new to CSS. When something does not work in a particular browser, many CSS developers will immediately employ a hack, seeing it as some kind of magic bullet. In fact, some developers seem to measure their expertise by the number of obscure hacks and filters they know. However, not all CSS problems are the result of browser bugs. As you will see in Chapter 9, many problems arise from errors in your code or an incomplete understanding of the CSS specification. Even if a problem is the result of a browser bug, you may not need to resort to a hack. Unlike the printed page, the way a design is displayed on the Web has as much to do with the user and their setup as it has with the designer. If your design is off by 3 pixels in IE 5.0, as long as it doesn’t seriously affect the rest of your site and the page is usable, the bug probably isn’t worth fixing. If you do employ a hack to fix a minor display bug in an older browser, as well as making a lot of extra work for yourself, you could be building in problems for future browsers. Remember, it is the browser implementation of CSS that is the culprit here, not your site.

In CSS there are many ways to skin a template, so if something is causing a problem, try achieving the same effect another way. Many CSS errors are caused by overcomplicated code and markup. If you keep your code simple and clear, most hacks can be avoided. If you have done your homework and realize that the only option is to employ some form of hack or filter, you need to do so in a sensible and controlled manner. If your CSS files are small and simple, and you only need to employ a couple of hacks, it is probably safe to place these hacks in your main CSS files. However, hacks are usually fairly complicated and can make your code more difficult to read. If your CSS files are long, or you need to use more than a couple of hacks, you may be best separating them into their own stylesheets. As well as making your code easier to read, if a hack starts causing problems in a future browser, you will know exactly where it is. Similarly, if you decide to drop support for a particular browser, removing the associated hacks is as simple as removing the CSS file.

To help you choose the correct filter for the job, several sites have published tables outlining which filters work in which browsers. The best known and most up-to-date of these support charts can be found at Centricle.

Filtering separate stylesheets

Putting your hacks into browser-specific CSS files and then using filters to send them to the required browsers can greatly simplify hack management. There are currently two main ways of achieving this. One way is to use parsing bugs to send particular CSS files to the desired browsers using the @import rule. The other way is to use IE conditional comments.

Internet Explorer conditional comments

Conditional comments are a proprietary, and thus nonstandard, Microsoft extension of regular (X)HTML comments. As the name suggests, conditional comments allow you to show blocks of code depending on a condition, such as a browser version. Despite being nonstandard, conditional comments appear to all other browsers as regular comments, and so are essentially harmless. Conditional comments first appeared in IE 5 on Windows and are supported by all subsequent versions of the Windows browser.

To deliver a specific stylesheet to all versions of IE 5 and above, you could place the following code in the head of your (X)HTML document:
<!-- [if IE]
<style type=”text/css”>
@import (”ie.css”);

Versions of IE 5 and above on Windows would receive the stylesheet ie.css while all other browsers would simply see some commented-out text. With conditional comments you could target a particular browser such as IE 5.0:
<!-- [if IE 5]
<style type=”text/css”>
@import (”ie50.css”);

You could also target sets of browsers such as IE 5.5 and greater:
<!-- [if gte IE 5.5000]
<style type=”text/css”>
@import (”ie55up.css”);

Or IE 5 and IE 5.5:
<!-- [if lt IE 6]
<style type=”text/css”>
@import (”ie.css”);

This technique works extremely well and is relatively simple to remember. The main downside is that these comments need to live in your HTML, not your CSS. If at some stage you wish to stop supporting a particular browser, you will need to remove the comments from every page.

Tags: , , , , , , , , ,


Posted in CSS. 283 views
Responses are currently closed, but you can trackback from your own site.

No Comments

Sorry, the comment form is closed at this time.