Checkbox Label Positioning in CSS

Many decisions in form layout and label positioning are largely personal preference. Arguments can be made (and are) for a number of different general layouts. I prefer this:

Field/label positioning

Lining up the input fields gives a nice clean left edge line and allows the eye to travel the fields easily. Having the labels right aligned connects them to the fields much better than left alignment does.

I generally accomplish this layout for input type=texts, selects and textareas using the following HTML markup:

<p class="label_field_pair">
<label for="foo">Foo:</label>
<input type="text" id="foo" />
</p>

And the following CSS:

p.label_field_pair {
clear: both;
float: none;
}
p.label_field_pair label {
clear: left;
display: block;
float: left;
text-align: right;
width: 100px;
}
p.label_field_pair input {
clear: right;
float: left;
margin-left: 10px;
width: 200px;
}

The result looks like this

HTML/CSS diagram

I used to use the same general technique for checkboxes as well:

<p class="label_checkbox_pair">
<input type="checkbox" id="foo" />
<label for="foo">Foo</label>
</p>

And the following CSS:

p.label_checkbox_pair {
clear: both;
float: none;
}
p.label_checkbox_pair input {
clear: left;
float: left;
margin-left: 80px;
}
p.label_checkbox_pair label {
clear: left;
display: block;
float: left;
margin-left: 10px;
width: 200px;
}

This will generally produce a layout like this:

Checkbox/label layout

However I found that about 30% of the time, it did this instead:

Broken checkbox/label layout

Refreshing the page would fix it, but it happened with enough regularity on first load that it was simply unacceptable. I decided to use a different technique. Instead of floating both elements, I just padded the label and absolutely positioned the checkbox.

The HTML is the same:

<p class="label_checkbox_pair">
<input type="checkbox" id="foo" />
<label for="foo">Foo</label>
</p>

but the CSS is different:

p.label_checkbox_pair {
clear: both;
float: none;
position: relative;
}
p.label_checkbox_pair input {
left: 80px;
position: absolute;
top: 1px;
}
p.label_checkbox_pair label {
display: block;
margin-left: 90px;
width: 200px;
}

I use margin-left instead of padding-left for the label because the horizontal padding is inconsistently applied in browsers in relation to width (some include the padding in the width, others do not).

If you want to use this to replace the float technique for standard label/field pairs, the field still needs to be the floated element because the label is the variable height element in that case. Unfortunately this does not work well with textareas unless you set a height on the label because the absolutely positioned textarea will not expand the p tag down to the full height of the textarea.

Textarea overflow

This overflow means the textarea will overlap the field below it.

Anyway, this is how I've done the field layout now in FeedLounge, so far it seems to be working as expected. I often mean to write up things like this, but it takes forever so I rarely do. Was it worth it?

Have an alternate method you like? Leave a trackback or a comment...