Every control needs a label
The programmatic label is what screen readers announce. Three valid patterns:
-
<label for="id">Email</label> <input id="id">— best. -
<label>Email <input></label>— wrapping, also fine. -
aria-label="Email"— only when a visible label is impossible.
Placeholders are not labels.
Group related controls
Radios and checkboxes belong in a
<fieldset> with a
<legend>. Screen
readers announce the legend before each option.
Errors must be programmatic
-
Move focus to the first invalid field, or expose a summary with
role="alert". -
Associate the error message with the field via
aria-describedby. - Never rely on color alone — include an icon and text.
Autocomplete tokens
Use the
autocomplete attribute
on all common fields (email, given-name,
family-name,
street-address,
postal-code,
cc-number). WCAG 1.3.5
requires it, and password managers depend on it.
Required indication
Mark required fields visually
and programmatically (required
or
aria-required="true"). An asterisk alone is not enough.
