A modal that asks before something that cannot be undone: a title, what will happen, and a cancel and a confirm action. It closes only on them and Escape.
Options
| Choice | Values | Default | What it does |
|---|---|---|---|
sizesmbk-modal--size-<value> | smmd | sm | The greatest width the panel takes: the modal’s two narrower widths, since the question is short. |
inlinesmbk-modal--inline | On or off | Off | Shown in place with no scrim, for previews and documentation. |
Examples
Usage
The question, what will happen, Cancel and the action. Shown in place here.
Sizes
The modal’s two narrower widths.
Brand confirm
The brand tone, for an action that cannot be undone but destroys nothing.
Without icon
The icon is optional.
Guidelines
Purpose
Asks the reader to confirm before something that cannot be undone, such as deleting a project. It is a modal that stops the page, says what will happen, and offers two ways out: cancel, which harms nothing, and the action itself. Unlike the modal, it closes only on those two and Escape, never on a click beside it, so the question is never dismissed by accident.
When to use
- Before deleting, removing or overwriting something the reader cannot get back.
- Before an action that costs money or reaches other people and cannot be called back.
When not to use
Usage rules
Do
- Ask only before what cannot be undone.
- Say in the description exactly what goes ("Website redesign and its 24 pages").
Don't
- Ask before everyday actions: an alert dialog asked too often is confirmed without reading.
- Put a second destructive action in it.
Name the action after what it does, so the reader knows the result before pressing it.
A "Yes" makes the reader reread the question to learn what pressing it will do.
Anatomy
- The block, the modal's native dialog element over its scrim, with the alertdialog role. The modal's stylesheet draws it.
- The header part: an optional icon part and the title part, the question, on one line. There is no close button. While the confirm action is the danger one, the icon is drawn in the danger color.
- The body part: the description, what will happen, and anything more the question needs under it.
- A divider and the footer part, holding the cancel action and then the confirm action, at the end.
Behavior
Opens modally, with focus on the cancel action. Pressing cancel or Escape asks to close; pressing the confirm action calls onConfirm and then asks to close. A click on the scrim does nothing. A dialog that holds its own open state closes itself; one the page holds waits for the page to close it, through onOpenChange(false). It fades in and rises into place over its scrim as the modal does, and under reduced motion fades in place. The size axis sets the greatest width, the modal's small or medium; the panel shrinks with the window.
The inline flag renders the panel in place with no scrim, so it can be seen in the Showroom and in documentation.
Accessibility
What it does for you
- It has the alertdialog role, so a screen reader announces it as an alert: its title names it and its description is read with it as it opens.
- Focus starts on the cancel action, the one that harms nothing, so pressing Enter by habit cancels. Focus is held inside while it is open and returns to the opener when it closes.
- A click beside it never closes it, so the reader must choose.
- The title is a second-level heading unless
headingLevelgives another.
What you must do
- Write the title as the question ("Delete this project?") and the description as what will happen, in a sentence or two.
- Name the confirm action after what it does ("Delete project"), never "OK" or "Yes".
- Give the cancel action's words in the page's own language when the page is not in English.
How to test
- Press the control that opens it: focus is on the cancel action. Tab and Shift + Tab stay inside it.
- With a screen reader, it is announced as an alert dialog with its title and its description.
- Click on the scrim: it stays open. Press Escape: it closes, and focus returns to the opener.
- With text at 200% and the page 320 pixels wide, the panel shrinks with the window and both actions stay reachable.
Keyboard
| Key | What it does |
|---|---|
| TaborShift+Tab | Moves focus between the actions and anything inside, and holds it there. |
| EnterorSpace | Presses the focused action. Cancel has focus as it opens. |
| Escape | Asks to close, as cancel does. |
Source
The files the alert dialog is made of. Its folder on GitHub (opens in a new tab) holds them with its wrapper and its document.
Stylesheet
/* smbk-alert-dialog — Alert dialog. The modal with the alertdialog role, drawn by the modal's stylesheet: its
* markup carries the modal's block, size and part classes after its own mark, smbk-alert-dialog, so every rule of
* modal/modal.css and the shared dialog/dialog.css (the scrim, the motion, the page held still) draws it.
* This file holds no rules: the alert dialog's own class is only its mark in markup. */Tokens it reads
| Token and CSS | Value | Preview | Foundation |
|---|---|---|---|
| color.overlay.scrim--smbk-color-overlay-scrim | light: #00000080dark: #00000099changes with theme | Color | |
| motion.exit.duration--smbk-motion-exit-duration | 200ms | Motion | |
| motion.exit.easing--smbk-motion-exit-easing | cubic-bezier(0.7, 0, 0.84, 0) | Motion | |
| motion.enter.duration--smbk-motion-enter-duration | 320ms | Motion | |
| motion.enter.easing--smbk-motion-enter-easing | cubic-bezier(0.16, 1, 0.3, 1) | Motion | |
| space.8--smbk-space-8 | 8px | Spacing | |
| space.16--smbk-space-16 | 16px | Spacing | |
| layer.modal--smbk-layer-modal | 1300 | Stacking order | |
| space.stack.xl--smbk-space-stack-xl | comfortable: 24pxcompact: 16pxchanges with density | Spacing | |
| size.modal.sm--smbk-size-modal-sm | 400px | Size | |
| space.inset.2xl--smbk-space-inset-2xl | comfortable: 24pxcompact: 16pxchanges with density | Spacing | |
| border-width.hairline--smbk-border-width-hairline | 1px | Border width | |
| color.border.rim--smbk-color-border-rim | light: #ffffffe6dark: #ffffff0dchanges with theme | Color | |
| radius.container.lg--smbk-radius-container-lg | 16px | Radius | |
| color.surface.default--smbk-color-surface-default | light: #f3f5f8dark: #181a1cchanges with theme | Color | |
| color.text.default--smbk-color-text-default | light: #232527dark: #e7ebf0changes with theme | Color | |
| elevation.overlay--smbk-elevation-overlay | light: 0px 12px 16px 2px #373d431a, 0px 2px 8px 0px #373d4326dark: 0px 12px 16px 2px #00000026, 0px 2px 8px 0px #00000033 | Elevation | |
| space.inline.lg--smbk-space-inline-lg | comfortable: 12pxcompact: 8pxchanges with density | Spacing | |
| size.control.md--smbk-size-control-md | comfortable: 40pxcompact: 32pxchanges with density | Size | |
| space.inset.lg--smbk-space-inset-lg | comfortable: 12pxcompact: 8pxchanges with density | Spacing | |
| size.icon.lg--smbk-size-icon-lg | 24px | Size | |
| color.feedback.danger.icon--smbk-color-feedback-danger-icon | light: #cc0d0ddark: #fe7d6dchanges with theme | Color | |
| typography.heading-2xs-bold--smbk-typography-heading-2xs-bold-font-family--smbk-typography-heading-2xs-bold-font-size--smbk-typography-heading-2xs-bold-font-weight--smbk-typography-heading-2xs-bold-line-height--smbk-typography-heading-2xs-bold-letter-spacing--smbk-typography-heading-2xs-bold-text-transform | fontFamily: Funnel Display, Funnel Display Fallback, system-ui, sans-seriffontSize: min: 18px · max: 24pxfontWeight: 700lineHeight: 1.2letterSpacing: 0px | The quick brown fox | Typography |
| color.border.subtle--smbk-color-border-subtle | light: #c4cdd8dark: #2d3237changes with theme | Color | |
| color.text.subtle--smbk-color-text-subtle | light: #4e555edark: #9ba5b1changes with theme | Color | |
| typography.body-sm--smbk-typography-body-sm-font-family--smbk-typography-body-sm-font-size--smbk-typography-body-sm-font-weight--smbk-typography-body-sm-line-height--smbk-typography-body-sm-letter-spacing--smbk-typography-body-sm-text-transform | fontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 14pxfontWeight: 400lineHeight: 1.5letterSpacing: 0px | The quick brown fox | Typography |
| size.modal.md--smbk-size-modal-md | 560px | Size | |
| size.modal.lg--smbk-size-modal-lg | 800px | Size |
Manifest
{
"name": "alert-dialog",
"block": "smbk-alert-dialog",
"drawnBy": "smbk-modal",
"summary": "A modal that asks before something that cannot be undone: a title, what will happen, and a cancel and a confirm action. It closes only on them and Escape.",
"adapt": "css",
"axes": {
"size": {
"values": [
"sm",
"md"
],
"default": "sm",
"description": "The greatest width the panel takes: the modal’s two narrower widths, since the question is short."
}
},
"flags": {
"inline": {
"description": "Shown in place with no scrim, for previews and documentation."
}
},
"parts": [
"header",
"icon",
"title",
"body",
"footer"
],
"figmaNodeId": "8224:3557"
}