Forms: The Accessibility Critical Point
If I had to pick one topic to train teams on, it would be forms. They're the main interaction point on any site -- sign up, contact, purchase, log in -- and yet they're the components most often inaccessible. RGAA Theme 11 dedicates 13 criteria to forms. There's a reason for that.
Labels
Every field needs a visible label linked via for/id. Simple as that. And here's the thing I tell every team: placeholders are NOT labels. They disappear when you start typing, they often have insufficient contrast, and screen readers don't treat them as labels. I've taught this to hundreds of devs and the "oh, right" moment is always the same. Group related fields with fieldset/legend.
Required Fields
Don't just slap a red asterisk on required fields and call it done. Use required or aria-required="true" in code, add a visual indicator (asterisk + a global note explaining what it means), and remember that not everyone understands what an asterisk means.
Error Messages
An error message that just says "Error" in red helps nobody. Link messages to fields via aria-describedby, mark fields with aria-invalid="true", provide an error summary at the top with links to the problem fields, and auto-focus to that summary after submission. This is where most forms fail -- and where you can really make a difference.
Focus Management
Focus is what guides keyboard users through your form. Keep tab order logical (never use tabindex > 0), make focus visible on every field and button, move focus to the error summary after submission failures, and announce success clearly with focus on the confirmation message.
Accessible CAPTCHA
Traditional visual CAPTCHAs are an accessibility nightmare. Here's what works: reCAPTCHA v3 (invisible, behavior-based), honeypot fields (hidden trap for bots, invisible to humans), Cloudflare Turnstile (no visual challenge), or hCaptcha with audio fallback.
An inaccessible form is a closed door. Your users won't fight to get through it -- they'll simply go somewhere else.