Styles and Tables

Web Review
May 1999

For years now-- or months, depending on how new you are to this business-- you've no doubt been using tables to lay out pages. Side columns, navigation bars, colored boxes, and so forth, all get their shape from tables, which are used as a page layout mechanism for just about every major Web site you can name. Never mind that this isn't what tables are for, or that it's all David Seigel's fault; this is how things are.

Eventually, it is hoped, styles will replace the need for tables, and allow us to lay out our pages with positioned elements, and floated elements, and all manner of non-tabular mechanisms. This is one of the most basic promises of CSS: that we can take well-structured documents and make them look as though they were laid out with tables, and that we can completely change the layout of a page simply by using a different stylesheet.

Peaceful Coexistence

That day is not today, I'm sorry to say, nor will it be any time soon. For the forseeable future, as we slowly transit away from browsers which are dependent on tables and toward browsers which don't need them for page layout, we'll be moving through a period in which we'll have to make styles and tables work together. To that end, it behooves us to figure out how to make that happen.

In the first place, you have to realize that tables and styles don't get along terribly well. This is especially true in Netscape Navigator, which treats tables almost as though they're separate documents. Not quite, but almost. Thanks to this special bit of weirdness, styles generally aren't inherited into tables in Navigator. This is where most new CSS authors get into trouble. They take a page they've already written using a table, and assign a style to the BODY element.

And nothing happens, because where the table starts, the inheritance stops. Take, for example, setting a font and color for the document like this:

   BODY {font-family: Helvetica, Verdana, sans-serif; color: green;}

Anything before the first table in the document should be fine in Navigator, but content within the table (and probably after it, for reasons which are too strange to get into here) won't take the style. In Explorer, the font might make it into the table if it isn't too complex, but the color almost certainly won't.

Fortunately, there's a fairly simple fix for this particular problem. Simply add some table elements to the rule:

   BODY, TH, TD {font-family: Helvetica, Verdana, sans-serif; color: green;}

This effectively circumvents the problems which tables can introduce by "burrowing" into them, so to speak. Instead of relying on inheritance, we simply assign the styles directly to the cells of the table.

Styling Tables Themselves

Of course, there are other issues with tables and styles. You might want to set the background color of a table, for example, or maybe just part of it. That's easy enough in theory, but of course the reality is a little more complicated.

Let's say you want a table in which any row with a class of highlight has a silver background. The style would be thus:

   TR.highlight {background: yellow;}

That will work well enough in most browsers, thankfully. The thing about this approach is that only the table cells will make use of the styles. The space between the cells doesn't show the background color, at least in current versions of Web browsers, so you'll need to reduce the cellspacing to 0 in order to have the cells join up. Of course, you might need some cellpadding to compensate, but the table will probably look a little better with the padding than without.

Now let's assume that you wish to style only one row, and assign it an ID instead of a class. We'll assume that it's the first row, with an ID of head, and that it should have white color on a black background.

   TR#head {background: black; color: white;}

Sadly, this won't work in Navigator, which doesn't recognize IDs on table elements. So if you want to apply styles to table elements which will be seen in Navigator, then you'll need to avoid using IDs.

Speaking of things which won't work in Navigator, here's something you need to be careful about. Let's say you want to apply styles to an empty table cell, like this:

   TD.highlight {background-color: yellow;}

   <TD class="highlight"></TD>

In Navigator, this will result in a blank area which shows the background behind the table. no yellow will appear. This isn't necessarily wrong, but then, it probably isn't what you expected. It's more likely that you expected what Explorer does, which is to fill the empty table cell with the background color you specified. Regardless of which is right, if you want to make sure the background color appears, you need to have something in that cell-- even if it's just a nonbreaking space.

   <TD class="highlight">&nbsp;</TD>

And now, at last, we consider what happens when you apply styles to the TABLE element itself. Suppose you wanted a table with a gray background. No problem:

  TABLE {background: gray;}

The only thing is that Explorer will apply this color to the cells of the table, but not the space between the cells and rows. Navigator, on the other hand, fills the entire background of the table, even the spaces between cells. The only way around this is to once again set the cellspacing to 0, so that there isn't any space between cells. That way, there's no opportunity for the different behaviors to assert themselves.

Isn't It Ironic?

It may seem like a particularly cruel joke that the one thing which we need most to be well-behaved-- tables, the existing method for page layout-- are the source of more style-related headaches than almost anything else. And if it's a joke, then yes, the punchline is on you. This is not to say that tables and styles can't get along. They can, and do, almost every day. It simply takes a little extra effort and patience to get them to play nice together. If you invest that time, it's well worth it in the end.