Skip to lesson content
WCAG 1.3.1 · Level AEasy5 min readForms

Form Fields Without Labels

Overview

Every form input must have a programmatic label — either a <label> element, aria-label, or aria-labelledby.

WCAG Criterion:1.3.1
Conformance Level:Level A
Difficulty:Easy
Time to fix:~5 min
Category:Forms

The Problem

This pattern is inaccessible — avoid it.

[ AVOID ]
<input type="email" placeholder="Email">
<input type="password" placeholder="Password">
<button>Submit</button>

The Fix

Use this accessible pattern instead.

[ CORRECT ]
<label for="email">Email address</label>
<input id="email" type="email" autocomplete="email">

<label for="password">Password</label>
<input id="password" type="password" autocomplete="current-password">

<button type="submit">Sign in</button>

Step-by-step

  1. Add a <label> element with a for attribute matching the input's id.

  2. Or use aria-label="Email address" on the input directly.

  3. Do not use placeholder as the only label — it disappears when the user types.

  4. Group related inputs with <fieldset> and <legend> (e.g., radio button groups).

Framework Notes

How to apply this fix in your stack.

// React — associate label and input
<label htmlFor="email">Email</label>
<input id="email" type="email" />

FAQ