Accessible Web Forms: A Practical Guide
Web forms are where accessibility failures are most common and most costly. Here's what we've learned about building forms that work for everyone.
Forms are the primary way users interact with applications — they submit orders, create accounts, contact companies, schedule appointments. They’re also the most common place where accessibility breaks down. We’ve built forms across healthcare scheduling systems, SaaS onboarding flows, and public-facing marketing sites. Here’s what we’ve learned.
Every Input Needs a Label. Not a Placeholder.
Placeholder text disappears when the user starts typing. Screen readers don’t reliably announce placeholders. aria-label works but is invisible and easy to get wrong. Use <label> elements with explicit for attributes matched to the input id.
<label for="email">Email Address</label>
<input type="email" id="email" name="email" autocomplete="email" required />
Placeholder text can supplement a label, but it can never replace one.
Required Fields Need More Than an Asterisk
The asterisk convention is widespread but not universal. Always pair a visual indicator with a programmatic one:
<label for="name">
Full Name <span aria-label="required">*</span>
</label>
<input type="text" id="name" name="name" required aria-required="true" />
Also add a note at the top of the form: “Fields marked with * are required.” Don’t make users discover your conventions through errors.
Error Messages Must Be Specific and Proximate
When validation fails, the error must be:
- Near the field — not just a summary at the top of the page
- Programmatically associated — use
aria-describedby - Specific — “Enter a valid email address” not “Invalid input”
<input
type="email"
id="email"
aria-describedby="email-error"
aria-invalid="true"
/>
<p id="email-error" role="alert">
Enter a valid email address (e.g. [email protected])
</p>
The role="alert" causes screen readers to announce the error immediately when it appears.
Keyboard Navigation is Non-Negotiable
Every form element must be reachable and operable by keyboard alone. Tab order should follow the visual order of the page. Don’t use tabindex values above 0 — they create navigation chaos.
Visible focus rings are required, not optional. If your design removes the browser’s default focus outline, replace it with something equally visible.
autocomplete Reduces Friction for Everyone
The autocomplete attribute isn’t just a convenience — it’s an accessibility feature. Users with motor impairments, cognitive disabilities, or just a lot of browser sessions open benefit enormously from not having to type the same information repeatedly.
Use the WHATWG autocomplete values: name, email, tel, street-address, postal-code, cc-number, etc. These are standardized and browsers handle them reliably.
Test With a Keyboard, Then a Screen Reader
Before shipping any form, navigate it entirely by keyboard. Tab through every field. Submit it with Enter. Trigger errors intentionally and confirm they’re announced.
Then test with a screen reader. VoiceOver on macOS and NVDA on Windows are both free. The experience will surface problems that visual inspection misses every time.
Accessible forms aren’t a nice-to-have for a subset of users. They’re better forms, period.