Wednesday, September 29, 2010

Advanced form layout with CSS

A common way of laying out forms is to use a table to line up the labels and form controls,
although with the output being non-tabular in nature, this method is not recommended
(CSS should be used for presentation, including positioning elements on a web page)—it’s
provided here to show a (partial) table layout that can be replicated in CSS. For our first
three fields, a table-based form may have something like this:
<fieldset>
<legend>Personal information</legend>
<table class="formTable" cellpadding="0" cellspacing="0" border="0"
å summary="A contact details form.">
<tr>
<th scope="row">
<label for="realname">Name</label></th>
<td><input class="formField" type="text" id="realname"
å name="realname" size="30" /></td>
</tr>
<tr>
<th scope="row"><label for="email">Email address</label></th>
<td><input class="formField" type="text" id="email" name="email"
å size="30" /></td>
</tr>
<tr>
<th scope="row"><label for="phone">Telephone</label></th>
<td><input class="formField" type="text" id="phone" name="phone"
å size="30" /></td>
</tr>
</table>
</fieldset>

Because a class value was added to the
table, the contextual selector .formTable
th can be used as the selector for styling the
form labels, defining the text-align property,
along with other CSS properties such as
font-weight. Applying a padding-right value to these cells also produces a gap to the
right of the label cells. Another contextual selector, .formTable td, can then be used to
style the cells—for example, to add padding at the bottom of each cell. The image to the
right shows these styles applied to the various elements in the previous code block, along
with the styles shown in the “Adding styles to forms” section.
.formTable td {
padding: 0 0 5px 0;
}
.formTable th {
padding-right: 10px;
text-align: right;
font-weight: bold;
}
Although forms are not tabular in nature, using a table to create a form can result in a
pleasing visual appearance, with the labels right-aligned and placed next to their associated
labels. This kind of layout can be replicated using CSS, via a structure built from divs
to replace the table rows. This method retains semantic integrity, via the semantic relationship
created by the label and associated field’s id. Using CSS for form layout also
brings with it the benefit of being able to rapidly restyle and move form components.
<form action="http://www.yourdomain.com/cgi-bin/FormMail.cgi"
å method="post">
<fieldset>
<legend>Personal information</legend>
<div class="row clearFix">
<label for="realname">Name</label> <input class="formField"
å type="text" id="realname" name="realname" size="30" />
</div>
<div class="row clearFix ">

<label for="email">Email address</label> <input class="formField"
å type="text" id="email" name="email" size="30" />
</div>
<div class="row clearFix ">
<label for="phone">Telephone</label> <input class="formField"
å type="text" id="phone" name="phone" size="30" />
</div>
</fieldset>
</form>
Various styles are then defined in CSS. The form itself has its width restricted, and label
elements are floated left, the text within aligned right, and the font-weight property set
to bold. The width setting is large enough to contain the largest of the text labels.
form {
width: 350px;
}
label {
float: left;
text-align: right;
font-weight: bold;
width: 95px;
}
The form controls—the input elements—are floated right. Because only input elements
within the div rows should be floated (rather than all of the input elements on the page),
the contextual selector .row input is used. (The containing divs have a class value of
row.) The width setting is designed to provide a gap between the labels and input elements.
.row input{
float: right;
width: 220px;
}
Finally, to make a gap between the rows, a .row class
is added and given a margin-bottom value.
.row {
margin-bottom: 5px;
}

The method works fine in all browsers except Internet Explorer, which doesn’t apply
margin-bottom correctly. However, the slightly different layout in Internet Explorer can
largely be fixed by adding the following in a style sheet attached via an IE-specific conditional
comment:
.row {
clear: both;
margin-top: 5px;
}
Alternatively, add the following:
.clearFix {
display: inline-block;
}

No comments:

Post a Comment