Accessible Form Markup Essentials
Forms represent the one area of your web site where you absolutely must commit time and energy to ensure user accessibility. But before you can begin to lay out a web form, you need to craft some really solid markup that will provide a framework to which you can add some style.
Even though forms represent some of the most complex interactions that can occur on a web page, in many cases these interactions are only represented visually — via the proximity of a form element to its label
, or grouping by borders and background colors. Users of assistive technology such as screen readers may not be able to see these visual clues, so it’s vital that you support these users by ensuring accessibility. The key concept behind providing an accessible form is to have descriptive labeling of all its sections and input
elements.
In particular, this means the proper usage of two elements: label
and legend
.
There’s also an improperly held belief that the only way you can guarantee that a form displays properly is by using tables. All of the code reproduced here for forms is standards-based, semantic markup, so you’ve got no excuse for relying on tables now!
Labeling Form Elements
No matter how you style a form element and its label
, it generally conforms to a certain pattern:
- the form element itself
- a text label for the element
- a connection between the element and its textual description
This connection is made either through visual alignment, visual grouping, or some other visual indicator. In the image below, you can see that the form on the left makes a connection between the field element and its label purely through alignment, whereas the form on the right indicates a more explicit connection via the use of color.
When accommodating users of assistive technology in the creation of your forms, there’s one main question to consider. How can a user who’s unable to see a web page create the connection between a form element and its text label, without the visual cues of proximity or grouping?
The answer is the label
element. label
is a special element applied to a form element to allow its textual description to be semantically linked to the element itself, so any assistive technology such as a screenreader can read out that text when it encounters its partner form element.
In order to use a label
, wrap the textual description in a pair of label
tags, then add a for
attribute to the label
. The value of the for
attribute should be the id
of the form element with which you want to create a connection:
<label for="firstName">First name</label>
<input id="firstName" name="firstName" type="text" />
Now, when a screenreader encounters the firstName
field, it’ll also read out the text “First name” to the user, so he or she will know what to type into that field. The label
doesn’t have to be near the form element and neither of them have to be in any particular order — as long as the label
‘s for
attribute contains a valid reference, the relationship will be understood. However, having the label
right before the form element in the source order generally makes the most semantic sense.
A label
should be applied to any form element that doesn’t automatically include descriptive text, such as:
- checkboxes
- radio buttons
textarea
s- text fields
select
boxes
Submit buttons and submit images don’t require label
elements, because their descriptions are contained, respectively, in their value
and alt
attributes.
Of course, you can easily style the text inside the label
using CSS, so you can format the label
text in your forms in the same way as if you were using a span
, p
, or div
, but using a label
has the benefit of being much more accessible than any of those elements.
Grouping Related Elements
legend
goes hand in hand with fieldset
. In fact, the only element of which a
legend can be a child is a fieldset
. A fieldset
groups a series of related form elements. For instance, “street address,” “suburb,” “state,” and “zip code” could all be grouped under “postal address
.” You could create a fieldset
that groups all of those elements, and give it an appropriate legend
to describe that group:
<form action="example.php">
<fieldset>
<legend>Postal Address</legend>
<label for="street">Street address</label>
<input id="street" name="street" type="text" />
<label for=" suburb">Suburb</label>
<input id="suburb" name="suburb" type="text" />
<label for="state">State</label>
<input id="state" name="state" type="text" />
<label for="postcode">Postcode</label>
<input id="postcode" name="postcode" type="text" />
</fieldset>
</form>
Now that legend
is associated with all those form elements inside the fieldset
, when a person using a screenreader focuses on one of the form elements, the screenreader will also read out the legend
text: “Postal Address; Suburb.”
The benefit of the screenreader specifying both legend
and fieldset
becomes apparent when you have two groups of elements that are very similar, except for their group type:
<form action="example.php">
<fieldset>
<legend>Postal Address</legend>
<label for="street">Street address</label>
<input id="street" name="street" type="text" />
<label for=" suburb">Suburb</label>
<input id="suburb" name="suburb" type="text" />
<label for="state">State</label>
<input id="state" name="state" type="text" />
<label for="postcode">Postcode</label>
<input id="postcode" name="postcode" type="text" />
</fieldset>
<fieldset>
<legend>Delivery Address</legend>
<label for="deliveryStreet">Street address</label>
<input id="deliveryStreet" name="deliveryStreet"
type="text" />
<label for="deliverySuburb">Suburb</label>
<input id="deliverySuburb" name="deliverySuburb"
type="text" />
<label for="deliveryState">State</label>
<input id="deliveryState" name="deliveryState"
type="text" />
<label for="deliveryPostcode">Postcode</label>
<input id="deliveryPostcode" name="deliveryPostcode"
type="text" />
</fieldset>
</form>
As the image below shows, with the fieldset
‘s legend
elements in place it’s quite easy to determine visually which fields fall under which group, even on an unstyled form.
But, you ask, couldn’t the same visual effect be achieved using h1
elements instead of legend
elements?
Yes. However, the point of using legend
is that without proper semantic grouping and labeling, a screenreader user would become confused as to why he or she was required to enter “Address 1” twice. With the legend
included, the user will know that the second “Address 1” actually belongs to another group — the group for the delivery address.
So, by combining label
and legend
, we give visually impaired users the ability to navigate and fill in our forms much more easily. By using this combination as the basic structure for your forms, you’ll ensure that not only will they look fantastic, but they’ll be accessible as well!