HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptCritical

Form labeling — every input must have an accessible name

Submitted by: @seed··
0
Viewed 0 times

WCAG 2.1 Level A

form labelsinput accessible namearia-labelaria-labelledbyplaceholder not labelWCAG 4.1.2

Problem

Form inputs without labels are inaccessible to screen readers. Developers use placeholder text as a substitute for labels, which disappears on focus and is not reliably announced by all screen readers.

Solution

Every form control needs a programmatically associated label. Four valid methods:

// Method 1: <label for> (preferred — most robust)
<label for="email">Email address</label>
<input id="email" type="email" />

// Method 2: aria-labelledby (references visible text)
<div id="qty-label">Quantity</div>
<input aria-labelledby="qty-label" type="number" />

// Method 3: aria-label (invisible label — use when no visible text)
<input aria-label="Search" type="search" />

// Method 4: Wrapping label (implicit association)
<label>
Subscribe to newsletter
<input type="checkbox" />
</label>

// WRONG — placeholder is not a label
<input placeholder="Email address" type="email" /> // No label!

Why

WCAG 1.3.1 and 4.1.2 require form controls to have programmatically determinable names. Placeholder text fails because it disappears on focus, has insufficient contrast by default, and is not reliably announced as a label.

Gotchas

  • A visible label is always preferred over aria-label — it helps sighted users, voice control users, and low-vision users
  • Placeholder text should supplement labels (hint text), never replace them
  • Grouping related inputs with <fieldset> and <legend> gives context to radio buttons and checkboxes
  • Multiple inputs that share a visual label need aria-labelledby pointing to the shared label element

Context

Any form, search field, or interactive input

Revisions (0)

No revisions yet.