All form inputs have associated labels; placeholder text alone is insufficient
Why it matters
Placeholder text disappears when a user begins typing, leaving them with no reminder of what a field expects. Screen readers may not read placeholder text at all, or read it only once. When an input has no associated <label> or ARIA label, screen reader users hear only the input type—"edit text"—with no context about its purpose. WCAG 2.2 SC 1.3.1 (Level A) and SC 3.3.2 (Level A) both require inputs to have accessible names and purpose identification. Section 508 2018 Refresh 502.3.6 incorporates this. Every unlabeled form field is an enrollment, checkout, or support pathway rendered unusable for screen reader users.
Severity rationale
High because unlabeled form inputs are directly unusable by screen reader users who cannot determine a field's purpose from type alone, blocking form submission workflows.
Remediation
Associate every <input>, <textarea>, and <select> with a visible <label> element. Use htmlFor in React to bind them:
<label htmlFor="email">Email address</label>
<input id="email" type="email" placeholder="you@example.com" />
For inputs where a visible label cannot be shown (search bars in compact UIs), use aria-label:
<input
id="search"
type="search"
aria-label="Search products"
placeholder="Search…"
/>
For dynamically generated inputs or multi-step forms, use aria-labelledby to reference an existing heading or description:
<h2 id="step-title">Billing address</h2>
<input type="text" aria-labelledby="step-title" />
Placeholder text may supplement a label but never replace it.
Detection
- ID:
form-labels - Severity:
high - What to look for: Check every
<input>,<textarea>, and<select>element. Each must have an associated<label>element with aforattribute matching the input'sid, OR the input must have anaria-labeloraria-labelledbyattribute. Placeholder text alone does not count as a label for screen readers. - Pass criteria: Every form input has a visible, associated label via
<label for="id">or an ARIA label attribute. At least 1 implementation must be verified. - Fail criteria: Any form input has only placeholder text with no associated
<label>or ARIA label. - Skip (N/A) when: No form inputs exist on the page.
- Detail on fail: Count the affected inputs. Example:
"5 form inputs lack associated labels: email input uses placeholder='user@example.com', password input uses placeholder='Password', and 3 text inputs lack both labels and placeholders." - Remediation: Use semantic HTML labels:
Or use ARIA for dynamically generated inputs:<label htmlFor="email">Email Address</label> <input id="email" type="email" /><input id="dynamic-input" type="text" aria-label="Search query" />
External references
- wcag:2.2 · 1.3.1 — Info and Relationships
- wcag:2.2 · 3.3.2 — Labels or Instructions
- section-508:2018-refresh · 502.3.6 — Label Relationships
Taxons
History
- 2026-04-18·v1.0.0·Initial import from gov-section-508·automated