Forms allow us to collect input from users in an organized, predetermined fashion.
Options to mark up a form
<form action="/path/to/script" method="post">
<td><input type="text" name="name" /></td>
<td><input type="text" name="email" /></td>
<td><input type="submit" value="submit" /></td>
Using a simple, two- column table is one of the easiest ways to achieve a usable form layout. Using a table is sometimes the best way to achieve certain form layoutsâespecially complex forms that involve multiple controls like radio buttons, select boxes, etc. Relying solely on CSS to control the layout of complex forms can be frustrating and often involve adding extraneous <span> and <div> tags. Unless this particular layout is crucial to the visual design of the form, using a table isn't necessary.
Method B: Tableless, but cramped
<form action="/path/to/script" method="post">
Name: <input type="text" name="name" /><br />
Email: <input type="text" name="email" /><br />
<input type="submit" value="submit" />
This is a passable solution, but could visually render a bit on the cramped side. We also run into the problem of the form controls not lining up perfectly. We could space out the elements by adding some margins to the <input> elements using CSS like this:
Method C: Simple and more accessible
<form action="/path/to/script" id="thisform" method="post">
<p><label for="name">Name:</label><br />
<input type="text" id="name" name="name" /></p>
<p><label for="email">Email:</label><br />
<input type="text" id="email" name="email" /></p>
<p><input type="submit" value="submit" /></p>
It is convenient to contain each label and control in its own paragraph. When viewed unstyled, the default spacing of a paragraph should be enough to set the items apart in a readable way. Later, we could control precise spacing with CSS on <p> tags that are contained within our form:
#thisform p {margin: 6px 0;}
With this CSS, all <p> tags within this particular form would have top and bottom margins of 6 pixelsâoverriding the default margins that the browser imposes on paragraphs in the absence of any styling.
While each group (label and field) are wrapped in <p> tags, a <br /> puts each on its own line. Using a <br /> to separate the items gets around the issue of fields not lining up perfectly due to text labels of different lengths.
The <label> element: This can be used in two ways to make forms more accessible. The first step is to use <label> tags to associate the label text with its corresponding form control, whether it be a text field, text area, radio button, check box, etc. The second step is adding the âforâ attribute to the <label> tag as well as a matching id attribute to the form control it belongs to.
Creating label/ID relationships allows screen readers to properly read the correct label for each form controlâregardless of where each falls within the layout. Also, it adds structure to the form by adding meaning to these components.
They also create larger clickable areas for the controls (e.g. radio buttons, check boxes), making it easier for mobility impaired users to interact with the form.
Method D: Defining a form
<form action="/path/to/script" id="thisform" method="post">
<dt><label for="name">Name:</label></dt>
<dd><input type="text" id"name" name="name" /></dd>
<dt><label for="email">Email:</label></dt>
<dd><input type="text" id="email" name="email" /></dd>
<dt><label for="remember">Remember this info?</label></dt>
<dd><input type="checkbox" id="remember" name="remember" /></dd>
<dt><input type="submit" value="submit" /></dt>
Each form label is wrapped in a definition term tag (<dt>) followed by its associated form control wrapped in a definition description tag (<dd>). Doing this creates a pairing of label to form control. By default, most visual browsers indent the <dd> element on its own line.
Defining style: The simplest style we could add would be to easily remove the default indenting of <dd> elements within our form:
The table-like format of Method A could also be achieved by floating <dt> elements within our form:
By floating the <dt> elements to the left, the form controls contained in <dd> tags will align themselves to the right.
Adding tabindex, and a numerical value, enables users to navigate the focus of form controls with the keyboard (typically using the TAB key). Repeatedly hitting the TAB key will change the focus to the next form control, in an order that we can specify. By default, every interactive element has an implied "tab order," but using the tabindex attribute takes that ordering away from the browser, putting you in full control.
<form action="/path/to/script" id="thisform" method="post">
<p><label for="name">Name:</label><br />
<input type="text" id="name" name="name" tabindex="1" /></p>
<p><label for="email">Email:</label><br />
<input type="text" id="email" name="email" tabindex="2" /></p>
<p><input type="checkbox" id="remember" name="remember" tabindex="3" />
<label for="remember">Remember this info?</label></p>
<p><input type="submit" value="submit" tabindex="4" /></p>
Using tabindex to set focus order becomes even more useful for complex forms and those where there might be multiple input boxes or other form controls for a single label. It can also help mobility-impaired users by letting them navigate the form entirely with the keyboard.
Similar to tabindex, the accesskey attribute is another easily added feature that adds convenience and can be useful for mobility-impaired users.
<form action="/path/to/script" id="thisform" method="post">
<p><label for="name" accesskey="9" >Name:</label><br />
<input type="text" id="name" name="name" tabindex="1" /></p>
<p><label for="email">Email:</label><br />
<input type="text" id="email" name="email" tabindex="2" /></p>
<p><input type="checkbox" id="remember" name="remember" tabindex="3" />
<label for="remember">Remember this info?</label></p>
<p><input type="submit" value="submit" tabindex="4" /></p>
When adding the accesskey attribute to the <label> tag that surrounds the Name: text of our form, if the user presses the key we specify, the focus of the cursor will change to the field that's associated with the label. Depending on the system, the user will either use the ALT or CTRL key in conjunction with the 9 key that we've specified in the markup. Focus will immediately shift to the Name: field in our form.
Adding the accesskey attribute can be especially helpful when used on frequently used forms such as a search box or membership login. Without having to reach for the mouse, users can instantly change focus and start their query or input using only the keyboard.
Setting the widths of text inputs:
Form controls can be tricky to deal with in their varying widths and heights that are dependent on browser type. Typically, a designer might specify a width using the size attribute, adding it to the <input> tag like this:
<input type="text" id="name" name="name" tabindex="1" size="20" />
Setting a size of "20" specifies the width of the text input box at 20 characters (and not pixels). Depending on the browser's default font for form controls, the actual pixel width of the box could vary. This makes fitting forms into precise layouts difficult.
Using CSS, we can control the width of input boxes (and other form controls) by the pixel if we wish. For instance, let's assign a width of 200 pixels to all <input> elements in our form example.
#thisform input {width: 200px;}
Now, all <input> elements within #thisform will be 200 pixels wide. This width was applied to all <input> elements which we donât want, as the check box and submit button are also an <input> element, and therefore receive that same value. So instead of applying the width to all <input> elements, let's use the IDs that we set for the "Name" and "Email" controls only.
 #name, #email {width: 200px;}
Using <label> to customise fonts
We can utilize the <label> element to dress up the text, or alternatively we could add styles to all paragraph tags that fall within our form with a unique style.
If aside from labels, the form has additional instructions or text that is also contained within <p> tags, this additional text would inherit the same styles if we applied them to <p> tags within our form.
We could instead apply a generic style to all text within our form, and then use the label styling specifically for customizing form controls uniquely.
font-family: Georgia, serif;
font-family: Verdana, sans-serif;
You'll notice that we don't have to repeat the font-size: 12px; rule in the #thisform label declaration. Since <label> elements are contained within #thisform, they will inherit that property. It's always good practice to set shared rules at a high level, then override only those that are unique and necessary further down the element tree. If you wish to change the font-family for the entire form, you need only update one rule, rather than each place that the rule is repeated.
Alternatively, you could set the rule at a high level, say the <body> elementâonce. The entire document would inherit the font face, unless otherwise specified.
Using <fieldset> to group form sections
<form action="/path/to/script" id="thisform" method="post">
<p><label for="name" accesskey="9" >Name:</label><br />
<input type="text" id="name" name="name" tabindex="1" /></p>
<p><label for="email">Email:</label><br />
<input type="text" id="email" name="email" tabindex="2" /></p>
<p><input type="checkbox" id="remember" name="remember" tabindex="3" />
<label for="remember">Remember this info?</label></p>
<p><input type="submit" value="submit" tabindex="4" /></p>
Using the <fieldset> element is a handy way of grouping form controls into sections. Additionally, adding a descriptive <legend> will, in most browsers, add a stylish border around the form controls that you're grouping.
Using style to <fieldset> and <legend>
To stylize <fieldset>'s border, making it a bit more subtle, we'll use the following CSS:
font-family: Georgia, serif;
font-family: Verdana, sans-serif;
First, we're customizing the font, weight, and size of the <legend>. Second, for the 3-D effect, we've set the background to a light gray, and then we've added a single-pixel border around the whole <legend> that matches the border that we've used for the <fieldset> element. For the shading effect, we've overridden the border's color on the bottom and right sides only, with a slightly darker gray.
Font size percentages: Setting a font size at a high level and then using percentages further down the hierarchy makes for easier maintenance later on. Need to bump up the whole site's font size? Just make a single update, and the percentages will change accordingly. Ideally we'd set that initial size on the <body> element, and use percentages everywhere else.