Notifications & Dialogs
Alert and Message Dialogs
AvailableA dialog that requires the user to confirm or respond, such as "Are you sure you want to delete?"
Specification updated
- Enhancement#3421(opens in a new tab)AlertDialog: Clarify aria-modal guidance
What Is an Alert Dialog (role="alertdialog")?
An alert dialog is a modal that presents an important confirmation or warningsuch as "Are you sure you want to delete?" and waits for the user's response. Unlike a regular dialog, it explicitly communicates to assistive technology thatthe message itself is urgent and important.
By adding role="alertdialog" to a native <dialog> and opening it withshowModal(), you leverage the browser's built-in modal behavior (focus management, Esc key, background inertness) while also conveying "this is a confirmation warning."
Why Does Accessibility Matter?
- Screen reader users need to hear the "Delete your account? This action cannot be undone"title and description announced together the moment the dialog opens.
aria-labelledbyandaria-describedbymake this possible. - Because the action is irreversible, initial focus should go to the safe option (Cancel). This prevents accidental destruction if the user presses Enter out of habit.
- Esc should always provide a safe way out, and after the dialog closes,focus should return to the original button so the user does not lose context.
Live Demo (Recommended Implementation)
Press "Delete Account" below to open a confirmation dialog. Verify that focus lands on "Cancel" immediately after opening.
Try it: Enter to open, initial focus is on Cancel, Tab to move to Delete, Esc to close, focus returns to the original button.
Tip
With a screen reader, the moment the dialog opens you will hear something like "Delete your account? This action cannot be undone..., alert, dialog" -- the title and description are announced together. This is the effect ofaria-labelledby + aria-describedby.
Keyboard Interaction
| Key | Action | Priority |
|---|---|---|
| Esc | Close the dialog (treated as cancel; natively supported with showModal()) | Required |
| Tab / Shift + Tab | Cycle between buttons (focus is trapped within the dialog) | Required |
| Enter / Space | Activate the focused button | Required |
| (Immediately after opening) | Initial focus is placed on the safe-side (cancel) button | Required |
Required WAI-ARIA Roles and Properties
| Target | Attribute / Role | Meaning |
|---|---|---|
| Dialog element | role="alertdialog" | Conveys that this is an important confirmation or warning dialog. |
| Dialog element | aria-modal="true" | Indicates that the backdrop is inert and this is a modal (required attribute per APG specification). |
| Dialog element | aria-labelledby="titleId" | Points to the dialog name (the question text). |
| Dialog element | aria-describedby="descriptionId" | Associates body text explaining the severity of the consequences, announced when the dialog opens. |
| Cancel button | autofocus | Places initial focus on the safe-side action. |
Implementation: Recommended Pattern (Good)
Good / Recommended
Add role="alertdialog" to a native <dialog>, associate the title and description, and set initial focus to Cancel.
Markup:
<button type="button" id="delete">Delete Account</button>
<dialog id="confirm"
role="alertdialog"
aria-modal="true"
aria-labelledby="confirm-title"
aria-describedby="confirm-desc">
<h2 id="confirm-title">Delete your account?</h2>
<p id="confirm-desc">
This action cannot be undone. All your data will be lost.
</p>
<!-- Initial focus goes to the "safe" Cancel button -->
<button type="button" id="cancel" autofocus>Cancel</button>
<button type="button" id="confirm-ok">Delete</button>
</dialog>Open/close script:
const dialog = document.getElementById('confirm');
const openBtn = document.getElementById('delete');
const cancelBtn = document.getElementById('cancel');
const okBtn = document.getElementById('confirm-ok');
openBtn.addEventListener('click', () => dialog.showModal());
cancelBtn.addEventListener('click', () => dialog.close());
okBtn.addEventListener('click', () => {
dialog.close();
// ...perform deletion...
});
// showModal() enables Esc to close; focus returns to the delete button.Note
Adding role="alertdialog" overrides the <dialog> element's defaultrole="dialog". Since modality may no longer be implicitly conveyed, it is safest to explicitly include aria-modal="true" as well.
Anti-Pattern (Bad)
The example below is a window.confirm-style confirmation box built with a <div>.It works with a mouse, but it is not announced when opened, focus does not move into it, and it cannot be closed with Esc.
Delete your account?
Try it: Opening does not trigger any screen reader announcement. Tab escapes to the background. Esc does not close it. Yes/No are spans and cannot be selected with the keyboard.
<!-- window.confirm-style DIV hack -->
<button type="button" onclick="showConfirm()">Delete Account</button>
<div id="box" class="box" style="display:none">
<p>Delete your account?</p>
<span onclick="hide()">No</span>
<span onclick="doDelete()">Yes</span>
</div>
<!-- No role, no focus management, no Esc, close targets are spans -->Bad / Avoid
Problems with this implementation:
- Not announced -- without
role="alertdialog"oraria-describedby, the confirmation purpose is not communicated. - Focus does not move -- after opening, focus stays outside the box, and Tab escapes to the background.
- Esc does not close it -- there is no safe way to dismiss.
- Options are
<span>elements -- they cannot receive focus and cannot be selected with the keyboard. - No protection against destructive actions -- there is no initial focus on the safe option.
Tip
The more irreversible the action, the more critical announcement, focus management, safe initial focus, and Esc become.<dialog role="alertdialog"> provides an easy foundation for all of these.
Implementation Checklist
- Uses native <dialog> + showModal()
- Has role="alertdialog" and aria-modal="true"
- aria-labelledby associates the question text, aria-describedby associates the consequence description
- Initial focus is placed on the safe-side (cancel) button
- Tab cycles within the dialog and does not escape to the backdrop
- Esc closes the dialog
- Focus returns to the trigger element when closed
- Focus ring is not removed
Source (English):Alert and Message Dialogs Pattern — W3C APG(opens in a new tab)