Building Better Forms

When building forms, most of the time, you will have a label either to the left or above the field associated with the label. Designers come up with all kinds of crazy ways to handle the layout, but most are not semantic and require browser hacks. In the past, I have used the following markup:

Example 1: Semantic Forms Version 1 HTML

<form>
    <ul>
        <li><label>Label1</label><input type="text" value"" /><li>
        <li><label>Label2</label><input type="text" value"" /><li>
        …
    </ul>
</form>

The label can then either float left or right, or be displayed as block, depending on your needs. However, I recently saw on the social networking site Facebook.com a nice technique using the definition list tag <dl>. I found this particularly appealing, because browsers (by default) and designers apply less styles to <dl> tags, making the design more browser agnostic. Plus, it is semantic to use a <dl> tag anytime you have key/value pairs; in this case, the key is the label and the value is the field.

Here is an example of what a <dl> based form would look like:

Example 2: Facebook Message Form

Find a good definition list picture, since original Facebook Message Form graphic is lost.

To produce such a nice looking Form, your HTML will be something like:

Example 3: Semantic Form Version 2 HTML

<form action="someURL" class="clearfix" id="someID" method="post"><dl>
    <dt><label for="form-msg-to">To:</label></dt>
    <dd><input id="form-msg-to" name="to" type="text" value=""/></dd>
    <dt><label for="form-msg-subject">Subject:</label></dt>
    <dd><input id="form-msg-subject" name="subject" type="text" value=""/></dd>
    <dt><label for="form-msg-message">Message:</label></dt>
    <dd><textarea cols="30" id="form-msg-message" name="body" rows="5"></textarea></dd>
</dl></form>

And the associated styles:

#message form {
	/* Optional, just a little nice padding */
	padding: 3em 0pt 1em 9em;
}

#message dl {
	/* Replace with desired width */
	width: 47em;
}

#message dl dt {
	float: left;
	/* Spacing between label and field */
	padding: 0 1em 0 0em;
	text-align: right;
	/* Width of largest label */
	width: 6.5em;
}

#message dl dt label {
	/* Make whatever you like */
	color: #666;
	/* Labels with "for" attribute are clickable, ensure they look that way */
	cursor: pointer;
	display: block;
	/* Use whatever font-size you prefer */
	font-size: larger;
	/* Adjust padding to align with fields */
	padding-top: 0.5em;
}

#message dl dd {
	float: left;
	/* This is the padding between form field rows */
	margin: 0 0 1em;
	/* Remaining width dl - dt - padding */
	width: 39em;
}

#message input.txt,
#message textarea {
	/* Prevents x-browser bug */
	overflow: hidden;
	padding: 0.4em 0 0.4em 0.2em;
	width: 33em;
}

You may also need to add the "clearfix" style to the form if other elements depend on its layout, as currently its content floats, so it won’t have any height. Otherwise, the CSS comments explain what the rules are doing.