Orderly Form Layout

Tuesday, February 24, 2004

Making a form layout in two columns — with the names of the fields on the left and the input fields on the right in nice columns — has been a small challenge. Not extremely difficult, but also non-obvious. So I thought I’d share my solution here. Maybe if you come across this problem I can save you a couple of minutes.

Also: If you use a browser that doesn’t display my CSS the way I think it should, you can (please) let me know. The educational street should run both ways…

The Result

First, here’s the final result. The CSS info is included in the header (so just view the source).

And a screenshot:

CSS form layout screenshot

This has been tested and displays well in IE 5.5/Win, Firefox 0.82/Win, and Safari 1.2/Mac. Slight layout problems occur in IE 5.0/Mac, but they don’t affect the usability of the form.

Notes

Most developers would just use a table to handle this sort of layout, which would probably be just fine. (And you could argue that this is tabular data so there wouldn’t be a semantic problem.) Since I’m trying to fully explore content-style seperation techniques, I thought I’d challenge myself to figure out a way to do this using just the CSS box model.

So. First I chose to use headers to label the input fields because HTML doesn’t yet have a specific “label” tag. Since both headers and paragraphs are block elements, for layout purposes they’re interchangable. (The only different being semantic, obviously, and that browsers automatically add style to headers to make them distinct.)

I wrapped each header and input field pair in a div tag, figuring I could force the width of the input headers (h3) and then use the display: inline; attribute with the div to force the input field to come right after the fixed-width header. Seemed like a good idea.

(Zane asked me this weekend why I thought CSS was so counter-intuitive sometimes. I don’t have a good answer, but I have to admit after getting deep into the standard that it’s an absolute mess: it doesn’t allow designers to easily achieve what should be very simple layout goals (like this one — and just wait until I get to write about my latest headache). And then no two browsers support it in the same way, making it that much more useless if you are trying to design something more than a standard webpage template — unless you plan to spend hours on end ironing out all of the issues.)

Back to the issue at hand…

This didn’t work. One of my Windows browsers did a fine job laying out the code while the other seemed to just ignore my attempt to fix the width of the h4. Some online hunting taught me that I needed to, instead, use the float attribute inside the input header and input p tags to float those blocks left and right (respectively). (Note that float doesn’t affect the alignment of the text inside the block.) Then I needed to use clear: both; to force both boxes to align against the top of the div that encased them (instead of stacking). (I’m sure this is pretty confusing unless you’re looking at the source code.)

Getting to know how to properly use float and clear, by the way, is an important first step to understanding how to acheive complex visual design with CSS.

The only other problem I encountered was that the headers were vertically a few pixels off from the input fields, a problem remedied simply by placing vertical-align: top; attribute in the h3 tag.

And there you go (hopefully).

Anyway. Let me know if you found this useful and if I should continue doing these little write-ups. Thanks!