When to use tables for layout

In most cases CSS is nicer to work with and much more powerful than presentational markup. There is really no reason to use font-tags, align-attributes etc, since the same effect can be achieved through CSS. But tables-for-layout is a special case, since table-based layout has some specific properties, which cannot be achieved through pure CSS applied to table-less markup.

Consider this simple form:

For aesthetic reasons, we would like the left edges of the input-boxes to align vertically. Using a 2x2 table, this is trivial. But using CSS this is surprisingly difficult.

We could define a common, fixed size on the label elements, which would push the input fields to the same horizontal position. However this forces us to manually determine the length of the contents of the widest label, and use this as the fixed length for all labels. Suddenly we have a tight coupling between content and style-sheet, which was exactly what CSS was supposed to liberate us from!

Table-based

A 2x2 table. No fixed measurements.

CSS

Labels defined with a fixed size to 3.3 em, since this corresponds to the length of the string "Name:", which is the longest label.

But it gets worse. What if we were to change the text of a label slightly?

Table-based

Table adjusts automagically to content.

CSS

Ouch! Depending on your browser, the label "Username:" will be cropped, or the input box will be pushed right and the boxes dont align vertically any more.

Whats is the problem with CSS?

Generally speaking, the problem is that CSS as currently implemented doesn't support the concept of grids, where cells are aligned both vertically and horizontally. The CSS layout model is a flow-model, where size and positioning of boxes is determined by containment and by what follows immediately before in the flow.

The grid-model is more complex, since the size of an element may by determined by content in a different branch of the element-tree.

Table

Grid layout. The cells align horizontally and vertically.

CSS

Floating box layout. There is no easy way to automatically align the left edges of the input fields, since they are in different branches of the box-hierarchy.

We can align the fields manually by assigning the same specific width to every label. But the layout wont adjust automatically to changes in content, since the grid is only in our minds.

To be fair, the CSS 2.1 spec does support grid-based layout using pure CSS. Unfortunately Internet Explorer does not support this, hence it's not really relevant for real-world web design, even though it is supported in other browsers.

Note that any specific grid-based layout can be duplicated in pure CSS, using some amount of fixed measurements to emulate the grid - as long as the content is known beforehand. The CSS Zen garden shows that amazing results can be achieved under these circumstances. However, in this world of CMS'es and database-backed websites, its more the exception than the rule, that the content is known beforehand and never changes after the design is finalized.

Another example

This is a typical page template with a main content area, a side bar, a header and footer.

Header
Sidebar
.
.
Main content
.
.
.
.
Footer

As this is a template, we can't know if the content of the main area or the sidebar extends the furthest down the page, since this might vary from page to page. We can handle this by flowing the two content areas, and clearing before the footer. Now the footer will follow after the end of the longest of the content areas, whichever it is. So far so good.

But what if we want a different background color in the sidebar, extending from top to bottom?

Like this:

Header
Sidebar
.
.
Main content
.
.
.
.
Footer

Table

Header
Sidebar
.
.
Main content
.
.
.
.
Footer
Using a table for the two columns, it is easy. We just appy the color to the cell containing the sidebar.

CSS

Header
Sidebar
.
.
Main content
.
.
.
.
Footer

Using a CSS layout with floating boxes, the sidebar-box does not stretch to the bottom.

The solution proposed by CSS gurus seems to be to create a background image with a colored area overlapping with the sidebar-area (this is called "faux columns"). This seems to me amazingly cumbersome and inflexible, compared to how easy it would be with tables: just apply a background color to the sidebar-cell using the style-sheet. Here it seems that discarding tables for layout actually makes the CSS less powerful.

If the requirements are fancier, like drawing a border around the sidebar or bottom-align a background image behind it, it will require a deviously clever css hacker.

The bottom line is that the two-column page template design really calls for a grid.

The design is grid-like because we want both top and bottom edges of the parallel content boxes to align. This is done by stretching the shorter of the boxes, so it achieves the same height as the longer. By default, the size of a box is determined by the size of its content. We only need a grid, if we want boxes to stretch beyond the content-size, to achieve the same dimension as another sibling box.

So, when is a table the right solution?

A table is the right solution when we need one or more box to stretch beyond the natural (content-determined) size, depending on the size of sibling boxes.

CSS layout is powerful enough, though, that many seemingly grid-like layouts can be emulated using some amount of clever tricks and hacks. But these solutions - clever as they may be - is difficult to create and maintain, and dont really give any benefit compared to the much more straightforward use of tables for layout.