Notifications & Dialogs

Alert and Message Dialogs

Available

A dialog that requires the user to confirm or respond, such as "Are you sure you want to delete?"

Specification updated

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?

Live Demo (Recommended Implementation)

Press "Delete Account" below to open a confirmation dialog. Verify that focus lands on "Cancel" immediately after opening.

Confirmation Dialog with role=alertdialog

Delete your account?

This action cannot be undone. All your data will be lost. (This is a demo -- nothing will actually be deleted.)

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

KeyActionPriority
EscClose the dialog (treated as cancel; natively supported with showModal())Required
Tab / Shift + TabCycle between buttons (focus is trapped within the dialog)Required
Enter / SpaceActivate the focused buttonRequired
(Immediately after opening)Initial focus is placed on the safe-side (cancel) buttonRequired

Required WAI-ARIA Roles and Properties

TargetAttribute / RoleMeaning
Dialog elementrole="alertdialog"Conveys that this is an important confirmation or warning dialog.
Dialog elementaria-modal="true"Indicates that the backdrop is inert and this is a modal (required attribute per APG specification).
Dialog elementaria-labelledby="titleId"Points to the dialog name (the question text).
Dialog elementaria-describedby="descriptionId"Associates body text explaining the severity of the consequences, announced when the dialog opens.
Cancel buttonautofocusPlaces 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.

Custom Confirmation Box Without role

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" or aria-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

Field Notes — Where practice diverges from the APG

Placing initial focus on the safe action is the consumer’s job, not the library’s

The APG says
In confirmation dialogs for destructive actions, initial focus should land on the least destructive control, such as Cancel.
What practice does
The AlertDialog in headless libraries (Base UI, Radix UI, React Aria) focuses the first focusable element by default and makes no attempt to identify the "safe" button. Instead they expose props like initialFocus and leave the policy to the consumer.
Why
Which button is "safe" depends on DOM order, label wording, and application context — a library cannot know. So headless libraries guarantee the mechanics (moving, trapping, and restoring focus) and expose the policy as an API. Meeting the APG requirement is the consumer’s implementation: point initialFocus at the Cancel button, or place the safe control first in the DOM.

Adopted by:Base UIRadix UIReact Aria

Sources:Radix UI — Alert Dialog(opens in a new tab)Base UI — Alert Dialog(opens in a new tab)


Source (English):Alert and Message Dialogs Pattern — W3C APG(opens in a new tab)