Labels, Fieldsets & Legends
A form is only usable if people know what each field is for. Labels name individual controls, fieldsets and legends name groups of controls, and hint text explains requirements. Getting these right is the single biggest factor in form accessibility.
Two ways to label
- Explicit:
foron the label matches the control'sid. Works wherever the two are in the page. - Implicit: the control sits inside the label. Simpler, and common for checkboxes and radios.
Either way, clicking the label activates the control, and screen readers read the label when the control is focused. Try clicking the words "Remember me".
What not to do
<p>Email</p> <input name="email" type="email" placeholder="Email">
Text next to a field isn't a label unless it's connected. A screen-reader user tabbing to this field hears only "edit text". The validator flags it, and so would an accessibility audit.
Fieldset and legend
When several controls answer one question, group them in a <fieldset> and give the group a <legend>:
Screen readers announce the legend when entering the group, so "Express (next day)" is heard as "Delivery speed, Express (next day), radio button". Without it, a lone "Yes" or "No" radio button would be meaningless. Fieldsets are essential for radio groups and checkbox groups, and useful for any related set of fields.
Disabling a group
Setting disabled on a fieldset disables every control inside it at once. Untick the box to see it.
Hints and error messages
Extra guidance — format requirements, error messages — should be connected to the field with aria-describedby, so screen readers read it after the label:
Put hints before users type, not only as an error afterwards. aria-invalid="true" tells assistive technology a field currently contains an error.
Marking required fields
The required attribute tells browsers and screen readers the field is mandatory. Show it visually too — an asterisk with an explanation, or "(optional)" on the fields that aren't. If most fields are required, labelling only the optional ones is less cluttered.
Visually hidden labels
Occasionally a design has no visible label — a single search box with a button, for instance. Keep a label for assistive technology but hide it visually with a CSS utility class (don't use display: none, which hides it from screen readers too):
Try it yourself
Group the contact preference checkboxes in a fieldset with a legend, and connect the hint to the phone field: