In HTML forms we looked at the basics of creating HTML forms: GET vs POST, text fields, checkboxes, radio buttons and so on. In this tutorial we’re going to go a step further and look at some of the ways you can make forms more accessible and usable for your visitors.
Web accessibility is important because it makes it easier for users to visit and use your site. This means happier visitors and more traffic!
We’ll cover the following topics:
- Using the
fieldset
andlegend
elements to group form fields in a logical way - Adding labels to form fields with the
label
element - Controlling the tabbing order of the elements in a form
- Speeding up form access and improving accessibility through the use of access keys
By the end of this tutorial you’ll be well on your way to designing wonderfully accessible forms. Read on…
Grouping form fields with fieldsets
In the past you’ve probably built, or at least seen, complex forms with many, many fields to fill in. (Shopping cart checkouts spring to mind.) If the fields are all bunched together on the page, the effect can be confusing for the visitor, if not downright overwhelming.
An accessible form groups fields together so the form makes more sense and is less intimidating. You can of course do this visually with whitespace, colours, or separator bars. However, HTML gives us a way to group fields at a structural level instead – the fieldset
element. By grouping fields within fieldsets, you can not only visually group the areas of your form, but structurally group them too. This means that the browser knows which fields are grouped together – great for things such as screen readers, for instance.
Here’s a simple example. Let’s say we’re building the proverbial shopping cart checkout form. We might group the form fields into fieldsets such as billing address, shipping address, and payment details, as follows:
<form action="">
<fieldset>
<legend>Billing details</legend>
<p>Name: <input type="text" name="billingName"/></p>
<p>Address: <input type="text" name="billingAddress"/></p>
<p>Postal code: <input type="text" name="billingPostcode"/></p>
<p>Country: <select name="billingCountry"><option>Australia</option><option>Canada</option><option>New Zealand</option><option>United Kingdom</option><option>United States</option></select></p>
</fieldset>
<fieldset>
<legend>Shipping details</legend>
<p>Name: <input type="text" name="shippingName"/></p>
<p>Address: <input type="text" name="shippingAddress"/></p>
<p>Postal code: <input type="text" name="shippingPostcode"/></p>
<p>Country: <select name="shippingCountry"><option>Australia</option><option>Canada</option><option>New Zealand</option><option>United Kingdom</option><option>United States</option></select></p>
</fieldset>
<fieldset>
<legend>Payment details</legend>
<p>Card number: <input type="text" name="cardNumber"/></p>
<p>CVV code: <input type="text" name="cvvCode"/></p>
<p>Expiry date: <input type="text" name="expiryDate"/></p>
</fieldset>
<div id="buttons">
<input type="button" name="paymentButton" value="Make payment"/>
</div>
</form>
Here’s what the above form looks like:
Not the most attractive form admittedly, but you get the idea! (Don’t worry, we smarten it up in the Styling forms with CSS tutorial.)
The <fieldset></fieldset>
tags are used to group the fields into fieldsets. After each opening <fieldset>
tag, a legend
element is used to add a caption to the fieldset. This caption is not only useful as a visual indicator of the type of fields in the fieldset, but it’s also very handy for people who are using non-visual browsers such as screen readers.
Improving accessible forms with field labels
In the above example, we’ve simply placed the field labels ("Name:"
, "Address:"
and so on) before our fields in the markup. While this works, it also lacks any structural association between the field labels and the fields themselves. How is the browser supposed to know that "Address:"
is the label for the billingAddress
field, for example?
Luckily, HTML provides us with a way to structurally link field labels with the fields themselves: the label
element. The basic syntax is:
<label for="fieldId">label text</label>
<input id="fieldId" ...
The label is associated with its field using for="fieldId"
(so each field in the form needs to be given an ID).
Again, structural markup like this is great for people using screen readers. Rather than the screen reader just saying “Text field” for each field, it can now say “Billing name”, for example.
Here’s our above example rewritten using labels
to link each label with its respective field:
<form action="">
<fieldset>
<legend>Billing details</legend>
<p><label for="billingName">Name:</label> <input type="text" name="billingName" id="billingName"/></p>
<p><label for="billingAddress">Address:</label> <input type="text" name="billingAddress" id="billingAddress"/></p>
<p><label for="billingPostcode">Postal code:</label> <input type="text" name="billingPostcode" id="billingPostcode"/></p>
<p><label for="billingCountry">Country:</label> <select name="billingCountry" id="billingCountry"><option>Australia</option><option>Canada</option><option>New Zealand</option><option>United Kingdom</option><option>United States</option></select></p>
</fieldset>
<fieldset>
<legend>Shipping details</legend>
<p><label for="shippingName">Name:</label> <input type="text" name="shippingName" id="shippingName"/></p>
<p><label for="shippingAddress">Address:</label> <input type="text" name="shippingAddress" id="shippingAddress"/></p>
<p><label for="shippingPostcode">Postal code:</label> <input type="text" name="shippingPostcode" id="shippingPostcode"/></p>
<p><label for="shippingCountry">Country:</label> <select name="shippingCountry" id="shippingCountry"><option>Australia</option><option>Canada</option><option>New Zealand</option><option>United Kingdom</option><option>United States</option></select></p>
</fieldset>
<fieldset>
<legend>Payment details</legend>
<p><label for="cardNumber">Card number:</label> <input type="text" name="cardNumber" id="cardNumber"/></p>
<p><label for="cvvCode">CVV code:</label> <input type="text" name="cvvCode" id="cvvCode"/></p>
<p><label for="expiryDate">Expiry date:</label> <input type="text" name="expiryDate" id="expiryDate"/></p>
</fieldset>
<div id="buttons">
<input type="button" name="paymentButton" value="Make payment"/>
</div>
</form>
And here’s what it looks like. Notice that on most browsers you can click on the field labels to give focus to the fields themselves. This is particularly useful for those tiny checkbox and radio button fields!
Setting the tabbing order of form fields
As you probably know, with most browsers you can use the Tab key to move between the form controls and links in a page. Many people find this much quicker and easier than clicking on the page elements with their mouse (and of course many people don’t even use mice!).
This is great, but sometimes the tabbing order goes awry. The browser determines the tabbing order by the order the elements are placed in the markup, which usually works OK. However, consider the following example with form fields in a table:
<form action="">
<table style="width: 100%; border: none;">
<tr>
<td>Name:<br/><input type="text" name="billingName"/></td>
<td>Postal code:<br/><input type="text" name="billingPostcode"/></td>
</tr>
<tr>
<td>Address:<br/><input type="text" name="billingAddress"/></td>
<td>Country:<br/><select name="billingCountry"><option>Australia</option><option>Canada</option><option>New Zealand</option><option>United Kingdom</option><option>United States</option></select></td>
</tr>
</table>
</form>
Here’s how this form looks:
As a visitor you’d probably expect the tabbing order to be Name, Address, Postal code, then Country. If you try tabbing through the fields though, you’ll see that the tabbing order is the order that they appear in the markup: Name, Postal code, Address, Country.
We can fix this with the tabindex
attribute, like this:
<form action="">
<table style="width: 100%; border: none;">
<tr>
<td>Name:<br/><input type="text" name="billingName" tabindex="1"/></td>
<td>Postal code:<br/><input type="text" name="billingPostcode" tabindex="3"/></td>
</tr>
<tr>
<td>Address:<br/><input type="text" name="billingAddress" tabindex="2"/></td>
<td>Country:<br/><select name="billingCountry" tabindex="4"><option>Australia</option><option>Canada</option><option>New Zealand</option><option>United Kingdom</option><option>United States</option></select></td>
</tr>
</table>
</form>
Now the form fields are in the expected tab order – try tabbing through them:
Using access keys for quick keyboard access
To further improve accessibility for people who use the keyboard, you can assign access keys to your form elements. Visitors can then press the access key, at the same time as one or more modifier keys, to give focus to, or otherwise manipulate the element.
The following HTML elements can have access keys assigned to them:
a
(a link)- Generally follows the link when the access key is pressed.
area
(an image map “hotspot” link)- Generally follows the link when the access key is pressed.
button
(a form button)- Gives focus to the button, or on some browsers, “clicks” the button, when the access key is pressed.
input
(a form input control)- For
text
input types: gives focus to the control when the access key is pressed. For all other input types: pressing the access key usually “clicks” on the control (e.g. checks/unchecks a checkbox or “clicks” a button). legend
(a fieldset legend)- Gives focus to the first form field in the fieldset associated with the legend when the access key is pressed.
object
(a generic inclusion of an object, e.g. a Flash movie)- Generally gives focus to the object when the access key is pressed.
select
(a drop-down menu)- Generally gives focus to the menu when the access key is pressed.
textarea
(a multi-line text input control)- Generally gives focus to the textarea when the access key is pressed.
Indicating access keys
According to the W3C HTML specification, the browser should ideally indicate the access keys to the visitor somehow (e.g. by underlining the access key in the form label). In practice, hardly any browsers do this, so it’s up to you to indicate the available access keys to your visitors. You could, for example, underline or bold the appropriate letter in the label text.
An example
Let’s enhance our “form in a table” example above with access keys:
<form action="">
<table style="width: 100%; border: none;">
<tr>
<td><span style="text-decoration: underline;">N</span>ame:<br/><input type="text" name="billingName" tabindex="1" accesskey="N"/></td>
<td><span style="text-decoration: underline;">P</span>ostal code:<br/><input type="text" name="billingPostcode" tabindex="3" accesskey="P"/></td>
</tr>
<tr>
<td><span style="text-decoration: underline;">A</span>ddress:<br/><input type="text" name="billingAddress" tabindex="2" accesskey="A"/></td>
<td><span style="text-decoration: underline;">C</span>ountry:<br/><select name="billingCountry" tabindex="4" accesskey="C"><option>Australia</option><option>Canada</option><option>New Zealand</option><option>United Kingdom</option><option>United States</option></select></td>
</tr>
</table>
</form>
Here’s how it looks. Try pressing the access keys (don’t forget to hold down your browser’s modifier keys also):
Accessible forms go a long way to making your site easy and enjoyable to use. By using one or more of the above techniques — fieldsets, legends, labels, tab order, and access keys — you can help to make your forms more accessible to your visitors.
Leave a Reply