Standards · ARIA

State Widget state

aria-invalid

Indicates that a form control has failed validation. Pair with aria-describedby pointing to the human-readable error message so the screen reader announces both the invalid state and the reason.

When to use

On an input, textarea, combobox, listbox, or other form widget whose current value has failed validation. Set aria-invalid="true" after the user has had a chance to enter a value — usually on blur or on submit. Setting it on first render, before the user has typed, is annoying and announces empty required fields as invalid before the user has done anything.

Pair it with the actual error message. The pattern is:

  1. Render a visible error message with its own id.
  2. Set aria-invalid="true" on the input.
  3. Point aria-describedby at the error message’s id.

Screen readers then announce both the invalid state and the explanation: “Email, edit, invalid entry, please enter a valid email address”.

How to keep it in sync

Valid values are "true", "false", "grammar", and "spelling". In practice the common ones are "true" and "false". "grammar" and "spelling" are used by rich text editors to mark a specific span; most form workflows do not need them.

Default to "false" (or omit). When validation fails, set "true" and reveal the error message. When the user corrects the field, clear both — flip aria-invalid back to "false" and remove or hide the error message — at the same moment.

The HTML attribute required and the CSS :invalid pseudo-class operate independently. aria-invalid is the bit screen readers consume; the others are for browsers and styling. Keep them in sync.

Common failures

  • Setting aria-invalid="true" before the user has had a chance to interact with the field.
  • Marking a field invalid with no aria-describedby and no visible error message — the screen reader announces “invalid” with no explanation.
  • Leaving aria-invalid="true" after the user has corrected the value.
  • Pointing aria-describedby at an empty container, so the error announcement is silent.
  • Using aria-invalid on <fieldset> or other non-input containers — it is not meaningful there.
  • Relying on color alone to indicate the error state — aria-invalid helps screen readers; you still need a visible label or icon for sighted users (WCAG 1.4.1).

Example

<label for="email">Email address</label>
<input
  id="email"
  type="email"
  aria-invalid="true"
  aria-describedby="email-error"
  required
>
<p id="email-error">Please enter a valid email address.</p>