Unlabeled form inputs are completely invisible to screen readers — when a blind user tabs to an input field, their assistive technology announces only 'edit text' or 'text field' with no indication of what information belongs there. This violates WCAG 2.2 SC 1.3.1 (Info and Relationships) and SC 3.3.2 (Labels or Instructions), and constitutes a Section 508 2018 Refresh 502.3.3 failure. In a login form, the user cannot tell whether they are in the username or password field. In a checkout form, they cannot distinguish billing address from shipping address. The practical consequence: screen reader users abandon the form entirely, creating both an ADA compliance liability and lost conversions.
Critical because unlabeled inputs make forms completely unusable for screen reader users, constituting an absolute barrier rather than a reduced experience.
Associate every form input with a label using htmlFor/id pairing, a wrapping <label>, or an ARIA attribute. The placeholder attribute alone does not satisfy WCAG 2.2 SC 3.3.2 — it disappears on input and has low contrast. In src/components/forms/ or wherever form components live:
// Preferred: explicit label association
<label htmlFor="email">Email Address</label>
<input id="email" type="email" name="email" />
// Icon-only input with no visible label
<input
id="search"
type="search"
aria-label="Search products"
/>
// When label is elsewhere in DOM
<h2 id="billing-heading">Billing Address</h2>
<input
id="billing-street"
type="text"
aria-labelledby="billing-heading"
/>
Audit all <input>, <textarea>, and <select> elements. A placeholder text that says 'Email' is not a label.
ID: accessibility-basics.semantic-structure-aria.form-labels
Severity: critical
What to look for: Enumerate every relevant item. Examine all form inputs (<input>, <textarea>, <select>) across the project. Check that each input is associated with a <label> element via a for attribute matching the input's id, or wrapped inside a <label> tag, or has an aria-label or aria-labelledby attribute. Screen readers use these associations to announce the label when the field receives focus.
Pass criteria: At least 1 of the following conditions is met. Every form input has an associated label via <label for="id">, wrapping label, or ARIA labeling attribute. Before evaluating, extract and quote the relevant configuration or code patterns found. Report the count of items checked even on pass.
Fail criteria: Any form input lacks an associated label, or labels reference incorrect input IDs.
Do NOT pass when: The item exists only as a placeholder, stub, or TODO comment — partial implementation does not count as passing.
Skip (N/A) when: Never — all form inputs must be labeled.
Cross-reference: For related security patterns, the Security Headers audit covers server-side hardening.
Detail on fail: Specify which input elements or components lack labels. Example: "Email input in login form has no label. Search input in header uses placeholder-only with no label element."
Remediation: Form labels are essential for accessibility. Associate each input with a label:
<label htmlFor="email">Email Address</label>
<input id="email" type="email" />
Or use ARIA if a visible label is not desired:
<input id="email" type="email" aria-label="Email Address" />