Laying Out Forms
Forms and their labels can take a variety of formats - labels above fields, form fields in multiple columns etc. Here are three approaches to achieving the commonly used format of labels with their associated form fields to the right of them.
Approach 1: Tables
WHAT? Tables for layout??? Well, yes, but indirectly - Some would argue that form fields and their labels can be described as tabular data, and so can be slotted into a table that conveniently goes hand in hand with a grid-like presentational layout:
<table>
<tr>
<td><label></label></td>
<td><input /></td>
</tr>
<tr>
<td><label></label></td>
<td><input /></td>
</tr>
<tr>
<td><label></label></td>
<td><textarea></textarea></td>
</tr>
</table>
Some might say forms can be tabular data, some might say that this is a small pile of dingoes droppings - a cop out - hammering a cylindrical peg through a square hole. Not that I'm saying that, you understand...
Approach 2: Floated labels
If we were to assume that, semantically speaking, forms are best left out of tables, we would be left with HTML that might look something like this:
<form action="whatever.php">
<div><label></label><input /></div>
<div><label></label><input /></div>
<div><label></label><textarea></textarea></div>
</form>
As it stands, each input
element in this example will come straight after a label
element. Because labels are invariably different lengths, this won't leave a very attractive form - it would be better if the input
elements all lined up. What we can do is associate a width to the labels with CSS. These won't initially apply this property though because they are inline elements. But changing their display
to block
will put them on different lines to the input
elements, which we don't want in this situation. So here's the simple solution:
label {
clear: left;
float: left;
width: 7em; /* or whatever length suits */
}
Approach 3: Relative form fields
Staying with the same HTML as Approach 2, instead of pushing things about by manipulating the label
elements, you could do things the other way around and move the input
elements instead.
The following CSS takes the input
elements, sets their display
to block
(which, remember, will put them on the line below their labels) and then moves them all across, past the width of the labels and then bumps them up a bit so they are in line with them.
label {
display: block;
margin-bottom: -1em;
}
input {
display: block;
position: relative;
left: 7em;
top: -0.5em;
}