Last summer, I took over a web application that had been created this decade. It uses HTML tables for its layout. Seasoned web designers will recognize this as a bad idea. For everyone else, let me explain why.

When HTML was young, there were very few options for complex layout. You could use frames, or you could use tables. Tables allowed for some pretty complex layouts, but they also violated the HTML specification for tables.

The table element represents data with more than one dimension, in the form of a table.

Your website's layout doesn't count. Basically, tables should be used for spreadsheet-like displays, not for marking out the sections of your page. This is semantically incorrect.

But who cares about semantics, right? As long as it looks right, it is right, right? Well, no. Folks tend to forget that eyes aren't the only things that have to look at a web page. Computers also have to interpret your web site. Maybe they're parsing it for a search engine, or to find the relevant data for a read-it-later service, or because they're reading the page to a blind person. From the HTML 5 spec:

Tables should not be used as layout aids. Historically, many Web authors have tables in HTML as a way to control their page layout making it difficult to extract tabular data from such documents. In particular, users of accessibility tools, like screen readers, are likely to find it very difficult to navigate pages with tables used for layout.

The HTML spec technically has a way to indicate that you're using a table for layout, but it's still not a given that a screen reader will properly interpret the layout.

Smart designers have been coming up with CSS-based ways to lay out a site without using tables. They often involved floating and clearing divs, which works pretty well, but can be difficult for a novice to understand, and often involved a bit of trial and error.

There is another solution that, I feel, combines the best of both worlds. You can actually lay out your page with divs, and then use CSS to style the divs to act like a table!

Here's a proper table:

<table>
  <thead>
    <tr>
      <th>Header!</th>
    </tr>
  </thead>
  <tfoot>
    <tr>
      <td>Footer!</td>
    </tr>
  </tfoot>
  <tbody>
    <tr>
      <td>Row Cell!</td>
    </tr>
  </tbody>
</table>

Here's the same table as divs:

<div class="table">
  <div class="thead">
    <div class="tr">
      <div class="th">Header!</div>
    </div>
  </div>
  <div class="tfoot">
    <div class="tr">
      <div class="td">Footer!</td>
    </div>
  </div>
  <div class="tbody">
    <div class="tr">
      <div class="td">Row Cell!</div>
    </div>
  </div>
</div>

Then, using the following styling, you can make this act exactly like a table:

.table   { display: table; }
.thead   { display: table-header-group; }
.tbody   { display: table-row-group; }
.tfoot   { display: table-footer-group; }
.tr      { display: table-row }
.td, .th { display: table-cell }

Seems like a lot of extra work to achieve the same affect, right? What's the benefit? There are several. For one, in practice you wouldn't actually name your classes the same as their HTML table counterparts. You'd name them something that describes their actual purpose in your layout. This makes your markup not only semantically correct but also more descriptive of it's actual function. In addition, you now have a flexible layout that you can control entirely with CSS, which comes in handy if you need to change up your layout in a responsive design. Best of all, you've now completely separated the presentation from the styling, which is always a good idea.

For more information, see the "display" property in the CSS 2.1 specification.

Comment