Wednesday, February 10, 2010

Two-column Form Layout Without Floats

As part of my job, I work with HTML forms almost daily, and styling them is an ever-evolving challenge.

Clients like it when labels are horizontally aligned with inputs. It's the standard look, and it works well.

One of the big requirements is avoiding floats. Float behaviour is complicated and buggy, even outside of IE. Normally that's not a big issue, but in apps one can't predict where a given form will end up, what kind of custom widgets (that use their own funky float layout) will need to be part of it, etc. Basically, form CSS has to be rock-solid.

Markup has to be simple and valid XHTML. So no tricks like placing the input inside the label. And it sucks to litter markup with spans and whatnot.

There has to be allowance for error messages, help tips, overflowing label text, etc. Basically, no reliance on hand-tweaking content.

A good method that does not use floats is described in this A List Apart article:

It uses inline-block for labels - not great, because it's hard to put properly aligned help text after it. Same with error text.

The answer? Negative margins. Check this example (forgive the programmer art):

First, we keep label content to the left of everything else by assigning a width to it (as a block), and applying a left margin to other content in the form.

Next, we apply a negative bottom margin to every label. Any content that follows a label is "pulled up" vertically to appear as though they are on the same horizontal line.

For consistency across fonts and browsers, we assign a generous fixed height to the label, and make the negative margin match it. In theory, the fixed height can be anything, even zero - but IE6's overflow bug puts an end to that theory.

This brings up a big caveat with this method. If the label contains several lines of text, the browser will not auto-magically shift remaining content down, as it would with normal cleared floats. In the particular case of HTML forms, this is not an issue, given enough vertical spacing between inputs.

No comments: