Guides Forms

How to Create an Accessible Form: Labels, Errors, Focus, and CAPTCHA

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.
No, never. I keep repeating this because it's the most common mistake: the placeholder disappears the moment you start typing, it often has insufficient contrast, and screen readers don't treat it as a real label. Always use a visible, properly associated label. The placeholder can serve as a format example ("e.g., john@email.com"), but that's it.
Forget traditional visual CAPTCHAs -- they're an accessibility nightmare. Go with reCAPTCHA v3 (invisible, behavior-based) or Cloudflare Turnstile (no visual challenge). The honeypot technique also works great: a hidden field that only bots fill in, completely invisible to real users.
Here's the recipe: an error summary at the top with clickable links to each problem field. Each error message linked to its field via aria-describedby. Problem fields marked with aria-invalid="true". And after submission, focus automatically moves to the summary. It's this combination that makes all the difference.

Test your site's compliance

Scan your site and get a detailed report with AI recommendations.

Scan my site - €15