Post Archive

› June 26, 2005

CSS design for the future: workaround vs hacks

  • Reported by Alessandro

There are many resources on bugs, hacks and filters, but I believe too few on workarounds... so here's my attempt to shed a small light on good practices on CSS coding for browsers.

Everyone involved in web design, and more specifically in CSS coding, knows that mastering theory is needed to determine browser error versus human error. Theory is essential, but it's not enough, everyday we have to face browsers discrepancies, rendering problems and bugs. This, although initially discouraging, should instead be considered a challenge to our skills...

In one of my articles in Italian on CSS problem solving that I wrote last september, I outlined a simple three step process to deal with CSS problems in practice:

  1. If we know a bug, we can sometimes prevent it
  2. If it isn't possible, we can use a workaround
  3. If we tried everything without success, we can use a hack

The message is that hacks should be considered as a last resort, since in my opinion they aren't funny or logical, so they lack two of the features that makes CSS so charming.

But, before beginning with some pratical tips, let's try to define what hacks and workaround are.

A hack is a way to fool browsers.

A workaround is a way to fool rendering problems, and minimize the affected browsers.

Basically, hacks are browser-oriented solutions while workaround are CSS-oriented solutions. The problem with hacks is that at the moment we can't say how the'll behave on future browsers, while instead we can be sure that a perfect logical CSS workaround will serve our pages how we expect even in the future.

We should code for today, keeping an eye on the future. In doing this, we should code for the widest set of actual browsers we can. A good advice on this: "code for the best, fix for the rest". This will help you maintain your CSS light, clean and logical, and you can adjust it to fit for the weakests.

Now, let's start from the most widely known rendering problem in CSS: the IE 5.x wrong box model. This is I believe one of the most annoying problems we have to face everytime we deal with dimensioned block-level elements with padding (and/or borders). A possible way to avoid it is specify the just the width and declare margins and/or padding on the direct content, for instance:

div#content{width: 500px}
div#content h2{margin:1em 10px 0}
div#content p{margin: 0 10px;padding-bottom: 0.7em}

While this approach could be adopted in simple situations, in complex cases with more varied content, and in case where we have to use borders, it could be just too tricky or could need an extra container in the markup.

The use of hacks to fix IE5.x box model is the only hack I've encouraged to use in my articles, and the only one I've ever used. But between the many box model hacks, perhaps there's one wich is less painful and more future proof than others. On the CSS-d Box Model Hack Page it's named as Alternate Box Model Hack #3. In fact, it's half a hack, and for the other half is a workaround:

div#content{width: 480 !important;
    width /**/: 500px;padding: 0 10px}

The only part of the rule wich can be considered a hack is the empty comment before the semicolon, which hides the second declaration to IE6. Anyway, at the moment we can affirm that every future browser with a CSS support conforming to the specification will parse the correct width because of the !important keyword.

Talking about hacks: most of you know the Holly hack to fix some rendering problem of IE 6. Let's see it:

/* Hides from IE5-mac \*/
* html div#content{height: 1%}
/* End hide from IE5-mac */

In fact, it's a double hack, and to be sincere I've discouraged its use on my italian article. There are at least two ways to avoid it using workarounds instead of hacks:

div#content{height: 1%}
div#container>div#content{height:auto}

And here's the solution #2, with a single rule:

div#content{height: auto !important;height: 1%}

Dealing with floats on IE6 can be an hassle with bugs such as the three pixel jog or the peekaboo bug. But can we prevent or avoid these bugs without having to fix them? Yes, we can try to solve float problems with float itself. For what I've tried, seems to me that opposite floats can get rid of many float bugs that affect IE.

So here are the basic rules for a two column layout with fixed width:

div#container{width: 760px}
div#content{float: left;width: 500px}
div#sidebar{float: right;width: 160px}
div#footer{clear:both}

For a three columns layout with opposite floats the html is:

<div id="container">
<div id="header">Header</div>
<div id="main">
    <div id="content">Content</div>
    <div id="nav">Navigation</div>
</div>
<div id="extra">Extra column</div>
<div id="footer">Footer</div>
</div>

The only disadvantage is an extra wrapper for the center column and the navigation. But having source ordered columns will be a benefit for accessibility and search engines, so this will compensate it. Here are the basic css rules:

div#container{width: 760px}
div#main{float: left;width:540px}
div#content{float: right;width:400px}
div#nav{float: left;width:140px}
div#extra{float: right;width:220px}
div#footer{clear: both}

And there you have it. A basic set of rules to get two robust cross-browser CSS layout that work in a large set of browser, both modern and not so modern (they also work in IE5.x) without the need of hacks.

That's all for now. Finally, to honour a web-graphics good tradition, here are some resources on the topics we've covered:

Comments

1. June 27, 2005 12:49 AM

Quote this comment

Terrence Wood Posted…

I think the * html is a great hack that works well in a family of browsers (IE) which are known to have most of the CSS rendering problems amongst browsers in use today.

Yes, * html exploits a browser weakness, but so do the work arounds in this article, i.e. the lack of comprehensive support for !important, and child selectors. I think calling one a hack and one a work around is a little pedantic.

What are the advantages of * html? (1) less code in both CSS and HTML, (2) it doesn't declare rules as important (simply to exploit one browser), (3) it is clear that the rule is to fix IE, (4) the rest of the selector usually matches one somewhere else in the CSS for well behaved browsers, thus is easier to debug than child-selector workarounds.

I think disrupting the source order simply to fix the visual design of a site is truely the worst hack of them all, and I strongly encourage people not to employ this method in a real world situation for the following reasons: (1) your site may be viewed without CSS, (2) your site may be viewed with user CSS which overrides your CSS, (3) some of your users are machines (e.g. search engines, assistive technologies) and are not viewing the layout of your page, so (4) your navigation gets lost somewhere in the middle of your page, and (5) your last 'column' of content, and potential SEO keyword goodness, is pushed down past the footer (not sure about this because the 3-col layout example doesn't have a footer) or (6) is 'disconnected' from the previous column.

2. June 27, 2005 01:15 AM

Quote this comment

Alessandro Posted…

Hi Terrence, guess you've missed the aims of the article... anyway, free to tell. One of them was in fact start people thinking, so I can tell at least in this I've got it.

About sorce-ordered colums layout: the footer has been added to the html example, thanks for pointing that out. I'm not so sure having content on the north will be a disadvantage for accessibility and SEO...

It's possible also get a 3-cols layout wich uses opposite floats having the navigation before main content. The css snippet for the layout remains the same, while you just have to change the order of content and navigation in the markup.

3. June 27, 2005 01:26 AM

Quote this comment

Alessandro Posted…

Another small note to define better the thight boundary between hacks and workaround: a hack cannot be justified/explained by CSS specification, while a workaround can.

4. June 27, 2005 01:58 AM

Quote this comment

Terrence Wood Posted…

Hi Alessandro,

I got the point of your article, and in the most part I agree:

  • CSS is great in theory, but hard in practice due to differences in CSS support,
  • Avoid coding practices that cause these bugs to manifest themselves,
  • Use hacks as a last resort

All good stuff, illustrated with some good examples.

I simply add a counterpoint to the discussion:

  • Hacks and work-arounds both exploit weaknesses in browser rendering engines, the distinction is artificial. Indirectly I ask "is the child selector work-around for IE any better than the any other work-around?"
  • I assert that some hacks use less code and are easier to debug than others, and
  • hacking your HTML is worse than hacking your CSS, because your site is, hopefully, visited for it's HTML content, not your CSS or your visual design.

If I have missed anything, please let me know.

P.S. thanks for fixing my paragraphs in my last comment =)

5. June 29, 2005 02:41 AM

Quote this comment

Jo Posted…

What about the Web Modeling Language (www.webml.org) as a CSS alternative/successor?

6. June 29, 2005 09:46 AM

Quote this comment

Nathan Rutman Posted…

I don't understand the lack of emphasis on Conditional Comments to fix CSS bugs (which I find are mostly IE oriented anyway).

Conditional comments provide the following benefits:

  • Due to placing the logical construct in comments, non-IE browsers won't be affected.
  • More organization can be brought to your use of style sheets, linking to one standard-complient sheet and then using CC's to link to any additional sheets that change attributes accordingly.
  • Any hacks that do need to be used won't affect page validation. While "hiding" invalid CSS may make the standards dreamer in all of us cringe, we all know that standards are ultimately only as good as their implementation. Therefore, I for one don't mind advertising properly-formed CSS while using non-standard CSS for IE via conditional comments. The standards-compliant browsers will see standards-compliant CSS.
  • Different CC's can be used for different versions (one set of corrections for IE5, another for 5.5, and a third for 6+ if necessary).
  • Style sheets referenced through CC's won't be downloaded by browsers that don't need them. Not that we're concerned with load time for a 5k CSS file, but it's nice to know that we don't waste time with unnecessary processing. Isn't that what best practices are all about?

Anyway, I just thought I'd bring that up...
-Nate

7. June 30, 2005 07:22 AM

Quote this comment

Andrew Faulkner Posted…

I wrote an article approaching the same subject in a similar manner. Maybe it's useful to you or your audience?

Article

8. July 1, 2005 02:18 AM

Quote this comment

Sebastiaan Posted…

It's of course also possible to use the Conditonal Comments of Microsoft for IE - then all the hacks intended for just that particular version of an IE browser could be put in a separate CSS-file. Clean and hack-free - and only IE can read it.

9. July 7, 2005 01:24 AM

Quote this comment

Ari Posted…

as an alternative to do CSS properties that IE dont understand, i dig the concept of using attribute selectors instead, and it's pretty neat and cool too.

nice article btw! :)

10. July 22, 2005 11:26 AM

Quote this comment

John Posted…

I agree with Nathan and Sebastiaan, why muck up your main stylesheet with workarounds when you can remove them completely.

IE Conditionals and IE CSS filters are an excellent way of keeping workarounds and hacks seperate from your main stylesheet.

I realize using CSS filters inadvertently reintroduce hacks into your main stylesheet, but we live in an imperfect world, compromises must be made sometimes. It's alot easier to remove a CSS filter than hunt down a bunch of hacks amongst your styles when you decide to drop support for an older browser.

11. November 7, 2005 01:37 AM

Quote this comment

Kristjan Posted…

So I should not use hacks, because in your opinion, they are not funny or logical?

12. January 16, 2006 04:32 AM

Quote this comment

Matt Davies Posted…

Wouldn't life be easier if we only had one universal browser!

13. February 15, 2006 06:03 PM

Quote this comment

Joe Boy Posted…

I found the section on "For a three columns layout with opposite floats" very useful. I am fairly new to CSS and was having trouble implementing 3 columns for I.E. This work around seems to be very simple and ideal for what I was after - many thanks... This for me is far better than using a more complicated template that I would struggle to fully understand.