A form that marks invalid fields only with a red border or a generic banner leaves assistive technology with no text to announce -- the error state exists visually but is never exposed to the accessibility tree.
3.3.1 Error Identification
In Plain Language
3.3.1 Error Identification (Level A) says that when an input error is automatically detected, the item in error must be identified and the error must be described to the user in text[1]. Two conditions, both mandatory: which field, and what is wrong -- conveyed as text the accessibility tree can expose.
The criterion does not require a form to catch every possible mistake. It governs what happens once the form itself flags one. A red border plus a toast that says "please fix the highlighted fields" satisfies neither clause -- it identifies nothing by text and describes nothing by text.
Why It Matters
- A red
border-coloris a presentational CSS change. It never reaches the accessibility tree, so a screen reader moving focus into the field announces the label and value with no indication that the field is invalid. - A field marked only with
aria-invalid="true"tells assistive technology the state is invalid but carries no description of the problem. The state is exposed; the reason is not. 3.3.1 requires both. - A generic banner ("errors on this page") fails the identification clause: it names no field. A screen-reader user who hears it has to tab through the entire form guessing which input triggered it.
- An error indicated only by a warning icon with no accessible name is invisible to assistive technology and to anyone who cannot parse the glyph. Users with cognitive and learning disabilities, in particular, need the specific problem named in words -- "Enter a 10-digit phone number", not a red exclamation mark[1].
Examples
✔ Error message in text identifies the field and describes the problem
<label for="email">Email address</label>
<input id="email" type="email"
aria-describedby="email-error"
aria-invalid="true">
<p id="email-error" class="error-msg">
Enter a complete email address, such as john@example.com
</p>
✘ Only a red border -- no text message, no aria-invalid, no description
<!-- FAILS: no text error message, no aria-invalid -->
<label for="email">Email address</label>
<input id="email" type="email"
style="border-color: red">
<!-- User sees red border but screen reader announces nothing -->
There are 2 errors in this form
✔ Error summary lists each problem with links to the affected fields
<div role="alert" class="error-summary">
<h3>There are 2 errors in this form</h3>
<ul>
<li><a href="#name">Name -- enter your full name</a></li>
<li><a href="#phone">Phone -- enter a 10-digit number</a></li>
</ul>
</div>
✘ Does not identify which fields have errors or describe what is wrong
<!-- FAILS: no field identification, no error description -->
<div class="error-banner">
An error occurred. Please fix the highlighted fields.
</div>
<!-- Which fields? What is wrong? User must guess. -->
How to Fix It
- Render the error as text adjacent to the field. Describe the specific problem in words the user can act on -- "Enter a complete email address, such as name@example.com" -- not a generic "Invalid input". The text node is what 3.3.1 requires; the red border is decoration layered on top of it[1].
- Set
aria-invalid="true"on the input while the error is present. This exposes the invalid state to the accessibility tree so screen readers announce "invalid entry" alongside the label. Remove the attribute (or set it to"false") once the value passes validation -- leaving it stuck at"true"after a correction is its own bug. - Link the field to its error text with
aria-describedby. Give the error element anidand reference thatidfrom the input'saria-describedby. The screen reader then reads the description as part of the field's announcement, so the user hears the problem without having to hunt for it in the page. - For errors that appear after submit, use a live region. A summary rendered with
role="alert"(or anaria-live="assertive"container) is announced the moment it enters the DOM. Alternatively, move focus to the summary heading -- either pattern makes the error reach assistive technology without requiring the user to re-read the page. - Make the summary link to the fields it names. Each item in the summary should be an anchor to the invalid input's
id, so keyboard and screen-reader users can jump straight to the field instead of tabbing the whole form. This also satisfies the identification clause of 3.3.1: the link text names the field and the error. - Do not rely on color or icon alone. A red border or a warning glyph with no accessible name fails 3.3.1 and compounds a 1.4.1 Use of Color failure. Pair every visual indicator with text, and give any decorative icon either an accessible name (
aria-label) oraria-hidden="true"so it does not introduce noise.
References
- [1] W3C (2023). Understanding Success Criterion 3.3.1: Error Identification. W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/error-identification.html ↩ ↩ ↩