References

Beginner-friendly references for web development, with live, editable examples.

The HTML aria-errormessage attribute

ARIA Accessibility
In short

A field points at its error text with aria-errormessage, by id. The link counts only while the field's aria-invalid value flags an error, so the message has to be visible then, and hidden or unlinked the rest of the time.

Overview

The aria-errormessage attribute identifies the element that provides the error message for a field or widget, by its id. HTML has no attribute for this job, so there's nothing native to prefer. WAI-ARIA 1.2 deprecates global use, and the roles that keep it match those of aria-invalid.

The link depends on aria-invalid. Authors must use the two together. Setting aria-invalid to true makes the message pertinent, and browsers must not expose the link when aria-invalid is false. A valid field has aria-invalid=false or no aria-invalid at all.

The message has to keep pace with that state. While it's pertinent, it must not be hidden, so users can navigate to it. The rest of the time, authors must hide it or remove the attribute or its value. Browsers drop the link when the target is hidden or the id matches nothing.

A link doesn't draw attention to a message. You can use a live region, such as role="alert", when an error appears after an invalid value is entered. That tells assistive technology the user may benefit from the message even if it wouldn't otherwise be conveyed.

Syntax

<label for="start">Start time</label>
<input id="start" aria-invalid="true" aria-errormessage="start-err">
<p id="start-err">Use a time between 09:00 and 17:00.</p>

Values

Value
A single element id.

Example

Live example
<form id="slot">
  <label for="start">Start time</label>
  <input id="start" placeholder="10:30" aria-invalid="false">
  <button>Book</button>
  <p id="err" role="alert" style="color:#b91c1c;margin:8px 0"></p>
  <p id="out" role="status" style="overflow-wrap:anywhere"></p>
  <p>Enter 18:30 and press Book, then enter 10:30 and press it again.</p>
</form>
<script>
const form = document.getElementById('slot');
const start = document.getElementById('start');
const err = document.getElementById('err');
const out = document.getElementById('out');
form.addEventListener('submit', function (e) {
  e.preventDefault();
  const good = /^((09|1[0-6]):[0-5][0-9]|17:00)$/.test(start.value.trim());
  start.setAttribute('aria-invalid', String(!good));
  if (good) {
    start.removeAttribute('aria-errormessage');
    err.textContent = '';
    out.textContent = 'Booked. aria-invalid is false, and the script removed aria-errormessage.';
  } else {
    start.setAttribute('aria-errormessage', 'err');
    err.textContent = 'Invalid time. Use 24-hour time between 09:00 and 17:00.';
    out.textContent = 'aria-invalid is true, and the script linked the message.';
  }
});
</script>

Best practices

  • Write an aria-errormessage target that says what's wrong and what's required. For a time field, that means saying the time is invalid and giving the allowed range.
  • Update aria-invalid, the link and the message in one function, so a flagged field can't end up with an empty or stale message.
  • Put an empty live region in the initial markup, then fill and link it when the value fails. Initial markup is the most reliable way to get a live region registered.
  • As an alternative, let CSS reveal the message, hiding .field-error with visibility: hidden and showing it through the selector [aria-invalid="true"] ~ .field-error.

Frequently asked questions

Why use aria-errormessage rather than aria-describedby?
The aria-errormessage link counts only while the field is flagged invalid, and aria-describedby has no such condition. A field keeps its description when aria-invalid is false, so use aria-describedby for text that always applies.
Does aria-errormessage work without aria-invalid?
Not as a rule, because aria-errormessage isn't exposed on a valid field with no aria-invalid. Without aria-invalid, a field that fails a pattern check still exposes the link, but on an empty required field Chrome drops it while Firefox keeps it.
Can aria-errormessage reference more than one id?
WAI-ARIA 1.2 defines aria-errormessage as one id reference, while the 1.3 Working Draft allows a list. Chrome and Firefox expose both targets of a two-id value.
Which aria-invalid values keep aria-errormessage exposed?
The values true, spelling and grammar all keep aria-errormessage exposed, since only aria-invalid=false bars browsers from exposing it. The message is pertinent when aria-invalid is true, so that's the value to pair it with.
Can the aria-errormessage element exist before the field fails?
Yes, an aria-errormessage target can exist early, as long as it's hidden or not yet linked. A valid field may carry the attribute only if the referenced element is hidden.
Can JavaScript read the element aria-errormessage points to?
Yes, the ariaErrorMessageElements property returns the aria-errormessage targets as an array of elements. Support arrived in Chrome and Edge 135, Firefox 136 and Safari 16.4.