Accessible form structure
Label every control
Connect visible labels to controls so the form remains understandable, clickable, and navigable with assistive technology.
8 minute lesson
Every form control needs an accessible name. For visible fields, a real label is usually the clearest way to provide it.
Connect the label with matching for and id values:
<label for="email">Email address</label>
<input id="email" name="email" type="email">
Clicking “Email address” now focuses the input. Assistive technology can also announce the label when the control receives focus.
You can wrap a control instead:
<label>
Email address
<input name="email" type="email">
</label>
Both patterns work. I prefer explicit for and id values when the label and control are separate layout elements.
A placeholder is not a label. It disappears during typing, can have weak contrast, and often contains an example rather than the field’s meaning.
The name has a different job. It creates the key sent to the server. A control can submit correctly while still having no accessible name, so you need both.
Icon-only controls need a name too. Prefer visible text when space allows. Otherwise provide a concise accessible name, such as aria-label="Search".
Test the form by clicking every label. Then inspect each control in the Accessibility pane and check its computed name.
Lesson completed