Marking up forms
Posted Aug 12, 2004 at 12:30 AM
Forms are unique compared to other HTML elements, in that they are explicitly used to structure user-interfaces for the input of information from the client to the server. This is very different from the large remainder of HTML, which is primarily concerned with structuring documents. What follows are some thoughts around options for structuring HTML forms.
Minimum requirements for forms
Before proceeding with markup options for forms, it’s important to point out a few rules that should be followed in all of our form markup, without exception. Since forms provide the key mechanism by which we get information from the user, it’s a key area to get perfectly right for reasons of customer satisfaction. Here are the rules:
Assign unique ID’s to each form tag
This is for convenience in implementing style and behavior targeted at a specific form without the need for additional markup weight.
Use the label tag for every form field in the form
This is a three-step process, as follows:
- Use the name attribute for each form field.
- Use the label tag around the text that identifies each form field.
- Use the for attribute of the label tag to point to the form element’s name, to bind the label and the form field together.
Taking this approach:
- allows screen readers to properly identify the fields to the user, regardless of the markup surrounding and order of the label and form field tags.
- is semantically valid, since this is exactly what the label tag was intended to do, and by using them, we add meaning to the markup, which is always beneficial.
- creates a nice benefit for radio and checkbox form elements, in that the state of these fields are toggled when the associated label is clicked, which creates a larger clickable region for these fields, making them easier to use, regardless of whether the user’s impairment is a mobility, visual, or new-laptop-with-different-mouse one.
- provides a convenient way of targeting styles intended for form field labels separately from other, often explanatory, text that may reside within the form.
Note: of course, the exception here is for submit and reset buttons, since their label is really self contained in the value attribute.
For large forms, use the fieldset and legend tags to group the form into sections
- The legend serves as a label for the section, and is required when using a fieldset.
- By default, most visual browsers will render a border around the fieldset, using the legend as a section heading within the border. Of course, this can be overridden with CSS.
Stay away from input type=”reset”
For an interesting discussion of this, check out Jacob Nielsen’s article on this topic.
Ensure that your forms are valid XHTML 1.0 Strict.
When in doubt, validate. When confident, validate.
Markup options for forms
There are basically three options available for marking up forms. We’ll consider each approach here, discuss the pros and cons of each, and then make some recommendations.
Approach 1 – use tables
<form action="#" method="post" id="signinform"><table><tr><td><label for="name">User Name:</label></td><td><input type="text" name="name" /></td></tr><tr><td><label for="pass">Password:</label></td><td><input type="password" name="pass" /></td></tr><tr><td colspan="2"><input type="submit" value="submit" /></td></tr></table></form>- Download this code: /code/forms_01.html
An exception to the “don’t use tables for layout” rule? Perhaps. In general, we should strive to avoid this, but simply say that in certain cases, involving big and complex forms that utilize a lot of radio or checkboxes, using a table to markup the form may be best. Relying on simple markup and controlling layout with CSS can be a lot of work, and often will create a lot of meaningless generic div or span tags, an approach that is really no better than using a table in the first place. The case above, however, just does not have the necessary complexity to justify using a table for the form’s markup. Because the vast majority of forms are not complex, let’s consider the alternatives for simple forms.
There’s another aspect to this choice that’s often overlooked when taking a table-based approach to render forms. Unlike other information contained in a web page, forms have “user interface” as their fundamental nature—in most cases, they are not content. Rather than debate this any further, we’ll simply move on.
Approach 2 – use definition lists
<form action="#" method="post" id="signinform"><dl><dt><label for="name">User Name:</label></dt><dd><input type="text" name="name" /></dd></dl><dl><dt><label for="pass">Password:</label></dt><dd><input type="password" name="pass" /></dd></dl><dl><dd><input type="submit" value="submit" /></dd></dl></form>- Download this code: /code/forms_02.html
This choice is somewhat controversial, in that it’s on the borderline of what a definition list is intended for. However, it’s valid markup, and many are turning to this approach for structuring their forms. It’s not a terrible choice, because these lists are intended to represent 2-dimensional data, and those that take this approach argue that this is precisely what their forms are. Here are the benefits:
- Each dl tag wraps one form label (contained in the dt tag) along with its associated form element (contained in the dd tag). Doing this adds additional semantically correct structure that indicates that these items are related.
- Since the dt and dd tags are block elements by default, visual browsers will render them on separate lines by default. Of course, this can be overridden with CSS.
- By default, visual browsers will indent the dd tags, providing an ordered and logical default rendering that can also be overridden with CSS.
- This approach provides a great collection of structured style hooks without the additional weight of id or class attributes. We could even achieve a tabular format, if desired, by floating the dt element left in CSS.
Approach 3 – simple markup
<form action="." method="post" id="signinform"><p><label for="name">User Name:</label><input type="text" name="name" /></p><p><label for="pass">Password:</label><input type="password" name="pass" /></p><p><input type="submit" value="submit" /></p></form>- Download this code: /code/forms_03.html
This is the approach that should be used in most cases. It’s simple and predictable. When viewed without CSS, the p tags are enough to differentiate one label/field pair from another, which is good. CSS can be applied to add various styled implementations, within reason.
About this page
This page contains a single post from Daniel Boerner's blog, of which Boot Camp + Windows Vista = no more Airport Extreme reboots is the latest post.
Are there more posts like this one?
Possibly. Within this blog, this post is categorized under webdev and it was posted on August 12, 2004. Those would be good places to start looking for related posts.
Visitor comments
2 comments
» by eglasius on Jul 13, 2005 at 08:05 PM | #
» by Daniel Boerner on Jul 17, 2005 at 07:45 PM | #
This post is closed to new comments. Thanks to everyone who commented.