Missing Form Labels
Your form inputs have no labels — screen readers see blank fields with no instructions. Here's how to fix it properly.
What is this?
Imagine walking into a government office and being handed a form where every field is blank — no labels, no instructions, just empty boxes. You would have no idea what to write where. That is exactly what an unlabeled form field is like for someone using a screen reader. They land on an input and hear... nothing. No name, no hint, just silence.
Why it matters
- For your visitors: Screen reader users hear form labels read aloud when they focus an input. Without a label, they hear "edit text, blank" — which is useless. Even sighted users benefit from labels: clicking a label focuses its input, making forms easier to use on mobile.
- For your business: Forms are where visitors become customers. If someone cannot fill out your signup, contact, or checkout form, you lose them. Unlabeled forms are one of the most common accessibility failures on the web.
- The standard: WCAG 1.3.1 (Info and Relationships) and 4.1.2 (Name, Role, Value) both require that form inputs have accessible names. The simplest way is a
<label>element.
<label for="email">Email address</label>
<input type="email" id="email" name="email" />
<label for="password">Password</label>
<input type="password" id="password" name="password" /><input type="email" placeholder="Email" />
<input type="password" placeholder="Password" />
<!-- Placeholder is NOT a label! It disappears when you type -->How to fix it
React / Next.js
Every input needs a label. The htmlFor attribute (React's version of for) connects the label to the input by matching the input's id.
// src/components/login-form.tsx
export function LoginForm() {
return (
<form>
<div className="flex flex-col gap-2">
{/* htmlFor must match the input's id */}
<label htmlFor="email" className="text-sm font-medium">
Email address
</label>
<input
type="email"
id="email"
name="email"
placeholder="you@example.com"
className="rounded border px-3 py-2"
/>
</div>
<div className="flex flex-col gap-2">
<label htmlFor="password" className="text-sm font-medium">
Password
</label>
<input type="password" id="password" name="password" className="rounded border px-3 py-2" />
</div>
{/* For icon-only buttons, use aria-label */}
<button type="submit">Sign in</button>
</form>
);
}You can also wrap the input inside the label — no for/id pairing needed:
<label className="flex flex-col gap-1">
<span className="text-sm font-medium">Email address</span>
<input type="email" name="email" className="rounded border px-3 py-2" />
</label>Plain HTML
<form>
<!-- Method 1: Explicit label with for/id -->
<label for="name">Full name</label>
<input type="text" id="name" name="name" />
<!-- Method 2: Wrapping the input inside the label -->
<label>
Phone number
<input type="tel" name="phone" />
</label>
<!-- For visually hidden labels (e.g., search box), use sr-only -->
<label for="search" class="sr-only">Search</label>
<input type="search" id="search" name="q" placeholder="Search..." />
<!-- aria-label works too, but real <label> elements are better -->
<input type="search" aria-label="Search the site" placeholder="Search..." />
</form>Common mistakes to avoid:
- Using
placeholderas a label — it vanishes when users type and has poor contrast - Using
aria-labelwhen a visible<label>would work — visible labels help everyone - Forgetting to match the
forandidvalues — a label pointing nowhere is a label doing nothing
Missing form labels are the most common accessibility bug on the web. The cat sees this on almost every site and is deeply unimpressed. Fix your labels.
How the cat scores this
The cat checks every <input>, <select>, and <textarea> on your page to verify it has an accessible name. This can come from a <label> element (via for/id or wrapping), an aria-label attribute, or an aria-labelledby reference. Inputs with only a placeholder and no label get flagged. The cat also verifies that for attributes actually match an existing element id.
Further reading
- WebAIM: Creating Accessible Forms — comprehensive guide to form accessibility
- WCAG 4.1.2: Name, Role, Value — the standard for accessible names
- MDN: The label element — reference for proper label usage