Stacked Table Layout

Don’t Nest, Stack!

In this section we’ll look at a proper implementation of the table-based layout. Traditionally, most people would make this with a single, three by two table, with a colspan in the top and bottom rows. Then, as the site becomes more complex, a mess of nests ensues. So let’s start out right, and stack it instead. Observe:

The Header of the Example

Left Column




Links have a css hover.

Right Column

Welcome to the example!

This cell is in a table that is one of three that are stacked, not nested. The header and footer are one-cell tables, and the menu and content area are in a two-cell table. Everything is controlled by CSS. This layout linearizes perfectly, because nothing is nested. The two columns are always the same height, because they are table cells, not floated divs.

The 3 tables’ width is 100%, and I’m using a div with overflow:auto wrapper around the example to keep it from clearing the floated menu in IE, or ramming under it in real browsers; not necessary in a real full-page layout.

The Footer is One Table With One Cell.


Now let’s see just how un-messy Strict table markup can be.

<table class="lay">
 <tr><td id="ltop">The Header of the Example</td><tr>
<table class="lay">
  <td id="llft">
   <p><a href="#">Menuitem</a></p>
   <p><a href="#">Menuitem</a></p>
   <p><a href="#">Menuitem</a></p>
   <p>Links have a css hover.</p>
  <td id="lrgt">
   <p>Welcome to this table!</p>
   <p>This cell is bla bla bla…</p>
<table class="lay">
 <tr><td id="lbot">The Footer.</td></tr>

Notice the complete absence of deprecated transitional markup and nesting. But can’t we do the same with 4 divs, and thus eliminate table and tr? Sure, but the columns would be different lengths, and we’d need a jillion clever hacks to sort out float-wrapping bugs in IE. Also, we’d likely need some wrapper divs, with even more CSS.

No table summaries? No. Regardless of squawking validators, layout tables should not have summaries, labels, captions or anything else like that. They are invisible to the eye, and should also be invisible to the screen reader.

The CSS:

table.lay { border-collapse:collapse; margin:0; border:0;
            background:#DDDDFF; width:100%; }
#ltop, #llft, #lrgt, #lbot { margin:0; border:0; padding:10px; }
#ltop, #lbot { vertical-align:middle; background:#DDDDFF;
   font-family:'Century Gothic',sans-serif; text-align:center;
   letter-spacing:0.2em; color:#997766; }
#llft, #lrgt { vertical-align:top; font-family:Verdana,sans-serif; }
#ltop     { font-size:1.5em; }
#llft     { background:#E2DCC7; width:15%; } /* Look Ma! No gif! */
#llft>h1  { margin:4px 0; font-size:1em; color:#90752C; width:155px;
            border-bottom:2px dotted #D2CCB7; font-weight:bold; }
#llft p   { font:normal 90%/100% Verdana, sans-serif; text-align:left; }
#llft a   { text-decoration:none; color:#6666AA; }
#llft a:hover { background:#EEEEDD; }
#lrgt     { background:#FFFFFF; }
#lrgt>h1  { font-size:1.4em; margin:0 0 0.25em 0; letter-spacing:0.2em;
            border-bottom:2px solid #D2CCB7; padding-bottom:0.1em; }
#lrgt p   { font-size:80%; text-align:justify; }
#lbot     { padding:0; font-size:12px; }

Don’t bother criticizing it—there are many ways to write it, and we just have to fiddle with it until it produces the desired effects. Notes:

  • Like any good CSS, it takes charge and overrides browser defaults, duplicate styles are rolled up to the practical minimum, and it uses CSS shorthand as much as possible.
  • There’s more there than necessary, because I’m also overriding site defaults.
  • The menu column needs no invisible image, because I’ve set the width of #llft>h1 to 155px, which with the padding makes the column minimum width 175px. It will be either that or 15%, whichever is greater. The right column needs no width setting at all. It just uses the remaining available space to fill out the table to 100 percent.
  • It shrinks and grows with browser text size and zoom in both IE and FF. Except for the footer text, which I deliberately nailed at 12px.
  • It linearizes properly and is completely accessible.
  • It renders top, then middle, then bottom, because there’s no wrapper and no nest.
  • More children tags may be added to each ID, as needed. Note that the direct descendent > in the h1’s is normally not necessary, but I’m overriding a couple of site defaults in the example.

“Yeah, but that’s a very simple layout, not a practical web site!” Well, yes, but one can add as much complexity as needed without compromising the basic skeleton. It’s obvious how to add a right column, or split the header into 2 or 3 cells, or insert a horizontal menu or breadcrumb table, or even float the occasional image or text box in the content cell.

Next, we’ll explore fluid layout techniques.


Leave a Reply

Your email address will not be published. Required fields are marked *