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.

Forms are where conversions happen—sign-ups, checkouts, contact requests—so an unlabeled form is a direct loss of business and a top ADA-lawsuit target. Without a programmatic label, a screen reader announces an input as just “edit text,” giving no hint whether it wants an email, a password, or a phone number. Placeholder-only forms look fine to sighted users but are an invisible wall for assistive-technology users and people with cognitive disabilities.

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).

Common Mistakes

  • Using placeholder text as the only label (it disappears on input and often fails contrast).

  • Adding a <label> but forgetting the for/id association.

  • Labeling a group of radios or checkboxes without <fieldset>/<legend>.

  • Hiding labels with display:none, which also hides them from screen readers.

How to Test for It

  • Click each field’s label—focus should move to the input, which proves the association.

  • Tab through the form with a screen reader and confirm each field announces its purpose.

  • Run an automated scan for inputs missing an accessible name.

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