Form layout

Semantically speaking, should we be using tables to lay out forms, or should we be using some other mark-up combined with CSS? Responding to this question, Drew McLellan comments on Russell Beattie’s Notebook: [via Simon Willison]

I’m comfortable using tables for forms. My point of view is that they are interactive tabular data.

If you mark up your labels in a th, your form controls in a td and stick them both in the same row, you can justifiably represent these name/value pairs as a table. But, of course, that’s not the end of the story. What if you don’t want your labels next to your form controls? My contact form, for example, has labels sitting above the form controls.

Because you’ve just decided that your name/value pairs can and should go in a table, you have inherently defined how your form should look. Forms engage the user directly – more so than any other part of a website – how they are presented is extremely important. So although one can justify laying out a form in a table, it’s simply not flexible enough. Which begs the question: what mark-up should we use instead?

What we really need is some block level mark-up (to be compliant with XHTML Strict) which meaningfully associates the form control with its preceding label. And I reckon HTML 2.0 provides just the thing.

Enter the little-used definition list. By placing the label in a dt (definition term) element and the form control in a dd (definition definition) element, we can meaningfully associate one with the other. Consider this simple example:

<dd><input type="text" name="email" /></dd>
<dd><input type="text" name="name" /></dd>

If the side-by-side table layout is what you’re after, we can apply some simple styles, based upon Mark Newhouse’s superb ALA article, Practical CSS Layout.


   margin:0 0 0.5em 0.25em;

There will be those of you out there who say you can’t use a definition list for a form – it’s not a list of definitions. I would rebut with this: the HTML 4.01 specification says that a dl could be used for pairings other than definitions, citing a script (character/speech pair) as an example.

Using a dl is more flexible than tables, and lighter & more meaningful than divs or paragraphs. It’s what I’ll be using for all my forms in future. Update: Here’s a worked example.