Monthly Archives: February 2009

In an ideal world, HTML would mark up a document in a completely semantic way, with no extra nesting or non-semantic elements. There’s a very big stigma against use of “chrome-only” chunks of markup. I’d like to make the case that sometimes, such markup is, if not ideal, at least better than more popular alternatives.

Say you wanted a dynamically sized box to have nice borders with beveled or rounded 3D corners. Here’s the lightweight markup you start with (39 chars without content):

Unfortunately, CSS doesn’t give us any way to do that without specifying an exact height and width for the box — a major accessibility block. We need a nested container and a fake header (I’ll use the Yahoo! standard container model) in order to use the sliding doors technique in 147 chars without content:

Now we can reach that style (with an appropriately large image). I won’t go into details on how to make CSS sliding doors, as that’s well documented elsewhere. Here’s what the CSS for that might look like:

There are two markup problems with this: one, we’ve created non-semantic markup that looks semantic, and we’ve had to add three layers of nesting! How is this better than tables?

Even with all that, due to the 31px height that the chrome image has for the top gradient, we have to resort to negative margins for the innermost content wrapper to achieve centering of the content. Our content formatting CSS and chrome CSS are heavily intertwined. Even with that, we still have a large amount of padding on top and bottom that cannot be eliminated.

Here, our content formatting CSS is limited to a single rule, almost entirely separate from the chrome styling. A slate of generic rules sets up most of the styling for re-use in many rounded-corner type situations. The four corner pieces are positioned absolutely to occupy 1/4 of the box each (a small amount of overlap allows for IEEE floating point math oddities). The main container is set to position:relative to constrain the absolutely positioned elements.

Finished box with chrome divided into four more-or-less equal quarters of the container. Borders drawn for clarity.

The last rule hides all chrome-only elements from audio browsers, just to be on the safe side. They generally wouldn’t report empty spans, but this assures as much. The b tag is used for brevity, and shouldn’t cause any more trouble than a span.

Browser bugs

The one caveat I must offer: browsers sometimes have some odd rendering differences when it comes to the use of positioning within certain elements. divs will generally work flawlessly, but you’ll find that browser differences abound when it comes to positioning inside buttons and lis. In those cases, know that you’ll likely need to deliver different styles to various browsers.

Despite those limitations, I think you’ll agree that our finished markup and CSS is far more readable, maintainable and reusable than the first. Thoughts?