Creating Accessible Forms
Advanced Form Labeling
Introduction
The <label>
tag has limitations. It cannot provide multiple labels for a single form control or associate a single label with multiple form controls. Sometimes, there is no visible text label to associate with a form control.
The majority of these labeling limitations can be overcome with three ARIA properties:
aria-labelledby
aria-describedby
aria-label
aria-labelledby
A <label>
declares, "I am a label for this form control" by referencing the form control's id
attribute value:
With aria-labelledby
, the form field references the id
attribute of the text that acts as its label:
The form control declares, "I am a control labeled by this element."
Handling Multiple Labels
Because the id
attribute of each form control must be unique, a <label>
can only point to one form control. With aria-labelledby
, one element can label multiple form controls, and one form control can be labelled by multiple elements.
The following is a simplified example of a table that might be used for data entry. Each header cell (<th>
) functions as a visual label for all form controls in the column below it. The text inputs use aria-labelledby
to reference the header cell text.
Name | Age | Weight |
---|---|---|
HTML for the first header ("Name"):
HTML for the first text input:
This labels the text input with the "Name" text in the table header cell. This aria-labelledby
attribute would be added to all three Name fields, thus properly labeling all of them with one text node.
Building on this example, the table below has visual labels along the top and side—multiple visual labels for each input.
Name | Office Number | Phone |
---|---|---|
Cyndi | ||
Jared | ||
Jonathan |
HTML for the first field:
The cyndi
and officenum
values reference the id
attribute values of the "Cyndi" and "Office Number" table cells. A screen reader will read "Cyndi Office Number" when navigating into this field. The reading order of multiple labels is based on the order in which these values are specified.
As a general rule, if a single label is present for a single control, the <label>
element should be used to reference it. These labels provide additional functionality - clicking on them sets focus to or activates the control. This functionality is not available when using aria-labelledby
.
If a control has both <label>
and aria-labelledby
, screen readers will announce the aria-labelledby
text instead of the associated <label>
. Screen reader users will never hear the <label>
text.
aria-describedby
To associate descriptive text with a form control, use aria-describedby
. For example:
New password must be 8-15 characters and include letters and numbers.
<input type="password" id="resetpass" aria-describedby="pwnote"><br>
<span id="pwnote">New password must be 8-15 characters and include letters and numbers.</span>
- Because there is a single label,
<label>
is used rather thanaria-labelledby
. - The
aria-describedby
attribute points to theid
of the element containing the password requirements. Screen readers will typically read the label, then read the input type (text box, checkbox, etc., plus any necessary properties, such as if the field is required), and then read the description. Multiple elements can be referenced byaria-describedby
. Just separate the referencedid
values with spaces. - Screen readers announce
aria-describedby
content in addition to a label (e.g.,<label>
or<input aria-labelledby>
). It is not a substitute for a label—all inputs must have a label. - The
aria-describedby
attribute can also be used to reference descriptions that appear as 'tooltips'. Tooltips must become visible to sighted keyboard users when the control has keyboard focus, not just when the user hovers or clicks with a mouse.
Invisible Labels
Some form controls don't need visible text labels. For example, a text input adjacent to a Search button makes its purpose clear to sighted users. An additional visual text label would be redundant. In such cases, one of the following three techniques should be used:
title
attribute
If a form field has a title
attribute but no <label>
, screen readers will treat the title
as a label. This will also generate a tooltip on mouse hover, which could be either helpful or distracting.
aria-label
The aria-label
attribute can also be used. Like aria-labelledby
, aria-label
overrides <label>
.
Only one of these recommendations should be implemented. Using two or more together (e.g., a hidden <label>
and a duplicate title
attribute) can cause information to be repeated by a screen reader.
placeholder
The placeholder
attribute does not take the place of a <label>
. One limitiation with placeholder
is that it disappears once information has been entered into the field, making it more difficult for users to make corrections. Instead, we recommend the labeling strategies above.
Bad Example
Relies on placeholder
.
<input type="text" name="first" placeholder="First">
<input type="text" name="middle" placeholder="Middle">
Good Example
Replaces placeholder
with <label>
, and adds autocomplete
, which was absent in the bad example.
Last <input type="text" name="last" autocomplete="family-name">
</label>
<label>
First <input type="text" name="first" autocomplete="given-name">
</label>
<label>
Middle <input type="text" name="middle" autocomplete="additional-name">
</label>
Recap
- Use
<label>
wherever possible. It has universal browser and screen reader support, and mouse users can click the label to focus its form control. - Use
aria-labelledby
to overcome the 1:1 limitations of<label>
. - Use
aria-describedby
(in addition to a label) to associate descriptive text to the form control. - Use a hidden
<label>
, or atitle
oraria-label
attribute when a visible text label is not needed. - Placeholder text (e.g.,
<input type="text" placeholder="Search WebAIM">
) is not a substitute for a label.