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