Accessible, resilient forms: errors everyone can find and fix
Label every field and link its hints and errors with aria-describedby, show an error summary and move focus to it, choose when to validate, why not to disable the submit button, prevent double submission, and keep forms working without JavaScript.
Comes up in: React, Machine coding, Web fundamentals
Learn#
Rekha uses a screen reader. She fills a government form, presses Submit, and nothing seems to happen. Two fields turned red at the top of a long page, but no one told her screen reader.
An error summary is a box at the top of the form listing every problem, each linking to its field. When submit fails, move focus to it, so screen readers announce it and keyboard users start there:
<div id="error-summary">
<h2 tabindex="-1">There are 2 problems</h2>
<a href="#email">Enter your email</a>
<a href="#phone">Enter a 10-digit mobile number</a>
</div>
<label for="email">Email</label>
<input id="email" name="email" aria-invalid="true" aria-describedby="email-hint email-error">
<p id="email-hint">We send the receipt here.</p>
<p id="email-error">Enter your email</p>Every field needs a visible <label>. Hints and errors are linked with aria-describedby, so they are read along with the label.
Page
- (silence)
A screen-reader user submits the form with two mistakes. Without help, nothing is announced; they do not know it failed.
Read the steps as text
- A screen-reader user submits the form with two mistakes. Without help, nothing is announced; they do not know it failed.
- With an error summary: a box at the top lists both problems, and focus moves to its heading, which is read aloud.
- Each item is a link to its field. Activating one moves focus to that input.
- The input has aria-invalid="true" and aria-describedby pointing at its error text, so the error is read with the label.
Predict#
Predict first
The submit button stays disabled until the form is valid. What is the problem?
A disabled button gives no reason and often is not announced or reachable. Let users submit, then show clear errors. Disable only briefly, while a submission is already in progress.
Interview angle#
Say it like this — about 30 seconds
“Each field has a visible label, with hints and errors linked by aria-describedby and aria-invalid on invalid fields. I validate on submit, and after a field is touched. On a failed submit I show an error summary at the top, with links to each field, and move focus to it. I do not disable the submit button for invalid forms. To prevent double submission, I disable or ignore clicks only while a request is pending, and the server uses an idempotency key.”
Follow-up How do you prevent double submission?
Follow-up When should validation run?
Follow-up What is progressive enhancement for forms?
Practice#
Guided
Write showErrors: set field states, keep aria-describedby correct, and build a focused error summary.
Done when
- Invalid fields get
aria-invalidand their error id inaria-describedby, keeping hint ids. - Fixed fields lose both, and their error text is cleared.
- The summary has a focused heading with the right count and a link per error, in form order.
Remember#
Try to answer each card before you open it. Then add them to your reviews.
What links an error message to its input?
aria-describedby with the error element's id.
Where should focus go after a failed submit?
To the error summary at the top of the form.
Why not disable submit until the form is valid?
Users get no reason, and the button may not be reachable.
Two ways to prevent double submission?
Ignore clicks while pending, and an idempotency key on the server.
Go deeper
Four layers. Stop at the one your interview needs; each ends with a quick check.
The core ideaEvery round
Placeholders are not labels: they disappear while typing and have low contrast. Keep hints visible and linked with aria-describedby.
Check yourself: Is placeholder text a label?
No. It disappears while typing and is often not read as a label.
How it works underneathSenior rounds
tabindex="-1" lets script focus the heading without adding it to the Tab order. The GOV.UK Design System pattern, widely copied, puts the summary first and links each error Source: GOV.UK Design System: Error summary.
Check yourself: Why give the summary heading tabindex=-1?
So it can receive focus from script without becoming a tab stop.
Edge cases and trapsWhere people slip
Check yourself: When should inline errors appear?
After submit or after the user leaves the field, not on the first keystroke.
In productionStaff-level answers
Check yourself: Which WCAG criterion covers identifying errors in text?
3.3.1 Error Identification.
Finished the five steps? Mark it, and its cards join your reviews.
Last checked 2026-11-01. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.
Interview questions this answers
- How do you prevent double submission?