Tableless CSS form layouts - Part 1

I've been working with CSS for about 6 years now and have used it for layout in the last 3. In that time I've learnt a lot (mostly from trial and error) and I hope to start writing about it here. First up is form layouts.

Most online articles tell you how to create a CSS layout using floats when you have a simple form with a label and input box on each line. I will show you how to create a more robust design that can accommodate numerous other possibilities including mandatory fields, fieldsets, multiple checkboxes, radio buttons etc.

Step 1 : The basic HTML and CSS

First off let's start with establishing a clean slate to start with, we also want to give the form a set width:

form
{
padding: 0;
margin: 0
width: 348px
}

It is also a good idea to align those pesky input fields a little better:

select, input, textarea
{
vertical-align: middle
}

Let's start small - a basic input field and label combination:

<label for="firstName">First name</label>
<input name="firstName" id="firstName" /><br />
<label for="emailAddress">Email address</label>
<input name="emailAddress" id="emailAddress" />

This looks like this:



Step 2 : Aligning the "columns"

Now we'd like those columns to line up nicely like they would in a table so we introduce some float trickery. It would be nice if all forms had nothing but input fields like this but they don't. We can apply a float style to the label but can't apply a style to the input tag as sometimes it might be text, a list of radio buttons or more than one input field.

The answer is to add a span tag around the input tag and style that instead:

<label for="firstName">First name</label>
<span><input name="firstName" id="firstName" /></span><br />
<label for="emailAddress">Email address</label>
<span><input name="emailAddress" id="emailAddress" /></span>

And add the float styles:

label
{
display: block;
width: 145px;
float: left;
}

span
{
display: block;
width: 200px;
float: left
}

Our form now looks like this:


Step 3 : Aligning the "rows"

Now we want to space out our form rows nicely so instead of using a br tag we make each row a paragraph. We also need to implement the modified "clearfix" hack to force IE to enclose the floated contents of the paragraph as it doesn't if both enclosed elements are floats:

<p>
<label for="firstName">First name</label>
<span><input name="firstName" id="firstName" /></span>
</p>
<p>
<label for="emailAddress">Email address</label>
<span><input name="emailAddress" id="emailAddress" /></span>
</p>
p:after
{
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}

p
{
display: inline-table;
padding: 0 0 10px 0;
margin: 0;
}

/* Hides from IE-mac \*/
* html p {height: 1%;}
p {display: block;}
/* End hide from IE-mac */

And this gives us:

So far, so good, but what about more complex layouts? Read part 2...

10 January 2007