Developers

How to build accessible web forms everyone can use

Build accessible web forms with proper labels, clear errors, keyboard support and sensible captchas, plus a form accessibility checklist to copy.

Cover image: How to build accessible web forms everyone can use, a FormDoc guide

Accessible web forms are forms that anyone can fill in, including people who use a keyboard, a screen reader, voice control or a magnifier. The essentials are simple: give every input a visible <label>, use real HTML elements, explain errors in text next to the field, keep focus visible, and avoid puzzles that only some people can solve. Get those right and you’ve solved most problems.

The good news is that accessible forms are also easier for everyone else. Clear labels, helpful errors and forgiving inputs help a busy person on a phone just as much as someone using assistive technology.

Accessible web forms start with real HTML

Native elements come with accessibility built in. A <button> can be focused, pressed with Enter or Space, and is announced as a button. A <div> styled to look like one does none of that unless you rebuild it all by hand.

So use:

  • <form> around your fields, with a real <button type="submit">.
  • <input>, <textarea> and <select> for data entry, not custom widgets.
  • <fieldset> and <legend> to group related controls, like a set of radio buttons.

A plain HTML form posting to a form backend is already a strong starting point. It works without JavaScript, keyboard users can tab through it, and screen readers understand every part of it.

Labels: the most important fix

Every input needs a label that’s visible and connected to it. Connect them with for and id:

<label for="email">Email address</label>
<input id="email" name="email" type="email" autocomplete="email" required>

When the label is connected, screen readers announce it as the field gains focus, and clicking the label puts the cursor in the field (a bigger target for anyone with shaky hands).

Common label mistakes to avoid:

  • Placeholder instead of a label. The placeholder disappears when you start typing, so people forget what the field was for, and its pale text is often hard to read.
  • Labels that don’t match the field. If the label says “Email” and the field’s id doesn’t match its for, the connection is lost.
  • Vague labels. “Details” tells no one anything. “What can we help with?” does.

Hints such as format rules belong in visible text too. Link them to the field with aria-describedby so screen readers read the hint after the label:

<label for="phone">Phone (optional)</label>
<input id="phone" name="phone" type="tel" aria-describedby="phone-hint">
<p id="phone-hint">We only call if you ask us to.</p>

Errors people can understand and fix

An error is only useful if the visitor notices it, understands it, and knows how to fix it. That means:

  1. Say it in words, not only with a red border. Colour alone fails people who can’t tell colours apart.
  2. Put the message next to the field, and connect it with aria-describedby so it’s announced.
  3. Explain the fix. “Enter an email address like name@example.com” beats “Invalid input”.
  4. Keep what they typed. Never clear a long message because one field was wrong.
  5. Move focus sensibly. After a failed submit, focus the first field with a problem.

The browser’s built-in validation does a lot of this for free: it announces its messages and moves focus to the first invalid field. See HTML5 form validation for the attributes that switch it on.

If you show messages with JavaScript, put success and error text in an element with role="status" (or aria-live="polite") so screen readers announce the change without the visitor hunting for it.

Keyboard and focus

Try your form without a mouse. Press Tab from the top of the page and check:

  • Every field and the submit button can be reached, in a sensible order.
  • You can always see where focus is. Never remove the focus outline without adding a clear replacement.
  • Dropdowns, checkboxes and date pickers work with the keyboard alone.
  • Nothing traps focus, and nothing opens unexpectedly as you tab.

If tabbing jumps around the page, the visual order and the HTML order probably don’t match. Fix the HTML order rather than reaching for tabindex numbers.

Captchas and accessibility

Image puzzles are hard or impossible for many people: those who are blind, have low vision, or have some cognitive disabilities. If you need a captcha, prefer one that usually runs without a challenge, and test it with a keyboard and a screen reader.

Better still, lean on checks visitors never see. FormDoc’s hidden honeypot field is skipped by keyboard users (it has tabindex="-1") and hidden from view, and spam scoring and rate limits run on the server. The captcha comparison covers which options cause the least friction.

Form accessibility checklist

Use this before you publish any form:

Check How to test Why it matters
Every input has a visible, connected label Click each label; the field should get focus Screen readers announce the label
Required and optional fields are clear Read the form without looking at colours People know what they must fill in
Errors are in text and next to the field Submit an empty form Colour alone isn’t enough
Error messages explain the fix Read them out loud Visitors can recover quickly
Whole form works by keyboard Unplug the mouse, use Tab and Enter Many people don’t use a mouse
Focus is always visible Tab through on a light and dark background People need to know where they are
Text and borders have enough contrast Check with your browser’s developer tools Low-vision readers can see fields
Success message is announced Test with a screen reader Visitors know it worked
No time limits or puzzles required Fill it in slowly Everyone gets the time they need

Don’t forget what happens after Send

Accessibility doesn’t end at the button. The confirmation must be clear too. If you redirect to a thank you page, start it with a heading that says the message was sent. If you show the result inside the form, make sure it’s announced. The guide to a good form thank you page has more on what to write.

Common questions

Is a placeholder enough instead of a label?

No. Placeholders vanish while typing, are often low contrast, and aren’t reliably announced. Use a visible <label> and, if you like, a placeholder as an extra example.

Do I need ARIA to make a form accessible?

Usually very little. Native HTML elements with proper labels cover most needs. Use ARIA for the gaps, such as aria-describedby for hints and errors and a live region for status messages.

How do I mark required fields accessibly?

Add the required attribute so assistive technology announces it, and show it in the label text as well, for example “Email (required)”. If most fields are required, mark the optional ones instead.

Start from an accessible base

Every form template uses real labels and the hidden honeypot, so you can start from a solid base and adjust the wording. Connect it with a free key from app.formdoc.dev/new.

Keep reading