Form error messages.
For a form error to count as accessible it must do three things: identify the error in text, be programmatically tied to the faulty field, and be announced to the screen reader.
On most sites, the form is the single conversion path — the place where a visitor becomes a customer. An accessibility defect in the form is therefore more expensive than any other defect on the site: unreadable text on the home page annoys; a form that cannot be submitted loses business. Yet forms are the most neglected area, because testing is usually done without filling them in.
Four criteria together
Form errors are governed not by one criterion but by four that complement each other. Seeing all four together prevents the “we added an error message, done” fallacy.
- 3.3.2 Labels or Instructions — A. Every field must be labeled and the expected format stated up front. BEFORE any error.
- 3.3.1 Error Identification — A. When an error occurs, which field it is in must be stated in TEXT. A red border alone is not enough.
- 3.3.3 Error Suggestion — AA. Where possible, how to fix it must be stated too. Not “invalid” but “enter as dd.mm.yyyy.”
- 4.1.3 Status Messages — AA. A message appearing without a focus change must be announced to the screen reader.
The logic of the order: the best error message is the one that never appears. That is why 3.3.2 comes first — stating the format expectation up front lowers the error rate. Then identifying the error, then suggesting the fix, then announcing it. Most teams do only the second and skip the other three.
Color alone is not enough
The most widespread defect is marking the error only visually: the field’s border turns red and nothing else happens. This violates several WCAG clauses at once. A user with color blindness cannot tell the red apart; a user with a screen reader never sees the color; and neither learns WHAT the error is.
The correct behavior is using color as an additional cue — not the only cue. The error itself must be expressed in text, the text must sit right next to the faulty field, and it must be programmatically tied to that field. Color is an emphasis layer on top and must carry no information on its own.
The same logic applies to icons. An exclamation icon next to the field is invisible to the screen reader without alternative text; with the alternative text “error” it carries no information. If the information the icon should convey already exists as text, the icon should be treated as decorative and given an empty alternative.
The programmatic tie: binding the message to the field
The error text sitting under the field on screen creates a visual relationship but no programmatic one. When a screen reader user focuses the field, they do not hear the text below it — because that text is not part of the field’s accessible description. The relationship must be declared explicitly.
Two things are done together. The field is marked invalid, so the screen reader says “invalid entry” on focus. And the error text is bound as the field’s description, so the text itself is read too. Together, when the user reaches the field they hear both that it is faulty and why.
A frequent mistake is marking the field invalid without binding the text. The user then hears “invalid entry” but cannot learn what is invalid — and cannot fix the form. A half-implemented accessibility feature unsettles the user instead of informing them.
Announcing: the live region
If the page does not reload on submit — and in most modern forms it does not — the result message appears silently on the page. A sighted user notices it; a screen reader user does not, because their focus is still on the submit button and they have no idea something on screen changed.
The fix is marking the region where the message appears as a live region. That mark tells the screen reader: “if this area’s content changes, tell the user.” The critical detail: the live region must exist on the page BEFORE its content changes. A live region created together with the message goes unannounced in most screen readers.
So the correct pattern is keeping an empty live region on the page from the start and writing the message into it. In the docs this detail looks like a small note; in practice it makes the whole difference between an announced and an unannounced message.
If the live region is born together with the message, the message is never heard.
The three-state flow
For a form to count as accessible, all three states must be defined, and most forms define only two. The contact form on this site carries all three, and the suite measures each separately.
- Pending — after the submit button is pressed, until the result arrives. The button is disabled and the state is stated in text; a spinning animation alone is silent for the screen reader.
- Success — announced from the live region where the message lands, and focus can be moved to the result.
- Error — the error text is announced from the live region, the faulty field is marked, and focus moves to the first faulty field.
The focus move in the last item takes the user straight to where the fix is needed and makes a big difference in long forms. In a ten-field form, hearing “one field is invalid” and Tabbing from the top to find which one is a needless burden.
There is also the fail-open principle, which is about reliability more than accessibility: if the submission fails for a technical reason, the user must not hit a dead end. On this site, if the server does not respond, the flow hands over to an e-mail link — the channel never fully closes. On a form that is the single conversion path, this matters as much as accessibility.
How to write the error text
Once the technical side of the criteria is solved, a writing job remains — and it is often the part that makes the most difference. 3.3.3 “Error Suggestion” asks not only that the error be reported but, where possible, that the fix be stated — and that is what makes a message useful.
Bad error messages resemble each other: “Invalid input,” “An error occurred,” “Please try again.” None tells the user what to do. A good message carries three things — which field, what is wrong, what to do. “The phone number must be 10 digits; enter it without the leading zero” carries all three and leaves the user nothing to guess.
- Name the field — not “this field” but “E-mail address.” A screen reader user may hear the message out of context.
- Say what is expected — format, length, allowed characters. An example beats a description.
- Avoid accusatory language — “this format was not recognized” instead of “you entered it wrong.” The error results from the form’s expectation, not the user.
- No technical jargon — “validation failed” tells the user nothing.
- Say how many errors there are — with a summary at the top of the form, “3 fields need fixing” gives the user the scope.
There is also the matter of timing. Showing errors while the user is still typing — validating on every keystroke — is both irritating and noisy for the screen reader, because the live region keeps talking. The right moment is usually when the field is left; on submit, all errors are gathered together.
Finally: the best error message is the one that never appears. If the expected format is written under the field from the start, a date picker is offered for dates, and the phone field formats automatically — the error rate drops. Accessibility here overlaps entirely with usability; a good form does the same things under both headings.