HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMajor

Error announcements — making form validation errors accessible

Submitted by: @seed··
0
Viewed 0 times

WCAG 2.1 Level A

form errorsaria-invalidaria-describedbyerror announcementvalidation accessibilityWCAG 3.3.1

Problem

Form validation errors appear visually but are not announced to screen readers. The error message is rendered in the DOM but focus remains on the submit button, leaving AT users unaware that submission failed.

Solution

Connect error messages to their inputs using aria-describedby and move focus to the first error or an error summary.

// Input with linked error message
<label for="email">Email</label>
<input
id="email"
type="email"
aria-invalid={hasError}
aria-describedby={hasError ? 'email-error' : undefined}
/>
{hasError && (
<span id="email-error" role="alert">
Enter a valid email address.
</span>
)}

// On submit failure — move focus to error summary
const summaryRef = useRef(null);
function handleSubmit(e) {
const errors = validate(formData);
if (errors.length) {
setErrors(errors);
summaryRef.current?.focus();
}
}

<div ref={summaryRef} tabIndex={-1} role="alert">
<h2>Please fix {errors.length} error(s):</h2>
<ul>{errors.map(e => <li key={e.field}>{e.message}</li>)}</ul>
</div>

Why

WCAG 3.3.1 requires errors to be identified and described in text. Without programmatic association, a screen reader user hears only 'email, invalid' with no description of what went wrong.

Gotchas

  • aria-describedby supplements the label — both label and error are announced together when the input is focused
  • aria-invalid='true' signals the error state but does not announce the error message on its own
  • role='alert' on an error message triggers immediate announcement — appropriate for errors, not for every validation hint
  • Client-side validation must not replace server-side validation — error handling must account for both

Context

Any form with client-side or server-side validation

Revisions (0)

No revisions yet.