alert
A live region that conveys an urgent, time-sensitive message. Screen readers announce it immediately, interrupting the current speech. Use sparingly — reserve for genuine errors and warnings; misuse causes assistive-tech fatigue.
When to use
For messages that genuinely interrupt the user — a form submission that failed, a session about to time out, a connection lost. role="alert" is equivalent to aria-live="assertive" plus aria-atomic="true", which means the screen reader stops whatever it is announcing and reads the alert next.
Use it sparingly. Assertive announcements interrupt the user’s current task; firing one for every saved field or successful action is hostile. For non-urgent status changes, use role="status" (aria-live="polite") instead.
The single hardest rule: the alert element MUST exist in the DOM before the message is inserted, and the content MUST be added (not toggled from hidden) for the announcement to fire. Inserting <div role="alert">Error</div> from scratch is unreliable across screen readers. The safe pattern: render an empty <div role="alert"></div> at page load, then update its text content when an alert occurs.
When to use vs. status
Use role="alert" | Use role="status" |
|---|---|
| Form validation errors | ”Item added to cart” |
| Session about to expire | Search results count updated |
| Connection lost | ”Saved” indicator |
| Payment failed | Loading complete |
Common failures
- Alert element added to the DOM after the message — many screen readers do not announce.
- Toggling
hiddenon a pre-populated alert. The text-content change is what triggers announcement; visibility toggling alone may not. - Using
role="alert"for routine status. Drowns the user in interruptions. - Multiple alerts inserted rapidly — later messages queue behind earlier ones, sometimes for tens of seconds.
- Alert message that does not name the field or the cause — “Error” alone is useless. “Email address is required.” is actionable.
- Putting
role="alert"on a wrapper around a form, then expecting changes inside to be announced. Only the alert element’s own text changes trigger.
Example
<!-- Render this empty at page load -->
<div role="alert" id="formErr"></div>
<script>
// On submit failure:
document.getElementById('formErr').textContent =
'Email address is required.';
</script>