A modal interruption for a focused decision, confirmation, or short task — completed or dismissed before the page continues. If the user could keep working on the page, it isn't a Dialog.
Short decision or confirmation — footer actions end-aligned, dismissive before committing: ghost Cancel, then the primary (or danger) commit.
Compact modal task with one field and a committing primary action; anything longer than a field or two belongs on a page.
Longer read-only content scrolls in a constrained region (five size.control.md) while the title and footer never move.
A dialog blocks; make the interruption earn itself.
| Verdict | Rule |
|---|---|
| Do | Write specific, outcome-oriented titles (Delete project?, Invite member) — the title is the aria-labelledby target. |
| Do | Keep body copy short; when content must scroll, constrain only the scroll region — the title and footer stay stable. |
| Do | Order the footer dismissive-before-committing — Cancel is a ghost Button, destructive confirmation a danger Button paired 1:1 with irreversible actions. |
| Do | Honor the focus contract: trap inside while open, choose an intentional initial target, return focus to the trigger on close — native showModal() plus layer-2 behavior. |
| Do | Let the scrim dismiss, but keep explicit Cancel and confirmation actions on destructive or data-loss dialogs. |
| Don’t | Title a dialog with a generic Are you sure? — name the outcome instead. |
| Don’t | Put a long contextual task in a dialog — one field is a Dialog, extended contextual work is a Sheet, and a workflow that should own history is a page. |
| Don’t | Nest dialogs — close or replace the current one first. |