Dialog
Opens a focused window for one quick task, like renaming a goal.
Examples
Sizes
sm
mddefault
lg
Show close
truedefault
false
States
rest
hover
focus
active
disabled
Usage
When to use it
- Use
- A short task that finishes or cancels before the person goes on: rename, share, pick a plan.
- Use
- A form of up to three fields that does not need the page behind it.
- Use
- A confirmation that is not destructive and can be dismissed by clicking away.
- Not for
- A decision that must not be dismissed by accident, such as deleting. Use Alert dialog.
- Not for
- Details, filters or a choice that should rise from the bottom on a phone. Use Sheet.
- Not for
- A small panel anchored to a control. Use Popover.
Rules
9 rules
- Must
- Render DialogTitle in every dialog. Because without it a screen reader announces "dialog" with no name.
- Must
- Name the confirming button for what it does, such as Save name; it is the one lime button. Because OK or Yes sends the person back to the body to learn what the press changes.
- Must
- Put the quiet action before the primary in the footer markup; the footer reverses on a phone. Because DialogFooter is flex-col-reverse below sm, so this order puts the primary on top there and last on wide screens.
- Never
- Use Dialog for an action that cannot be undone; use AlertDialog, which ignores outside presses. Because a stray tap on the scrim closes a Dialog before the person has read what goes.
- Should
- Title the task in sentence case, such as Rename goal, not a question.
- Never
- Open a Dialog from inside a Dialog; show the second step in the same dialog body. Because a second scrim stacks on the first and focus must climb back through two layers.
- Should
- Use a page or a Sheet for more than three fields.
- Should
- Keep the dialog open on failure and show the error beside the field; there is no error part.
- Should
- Use Button pending for a slow save and disable Cancel if closing would lose work.
Accessibility
4 checks
- The panel is role dialog, named by DialogTitle and described by DialogDescription; the page behind is inert.
- Focus moves to the first control inside and returns to the trigger on close.
- Escape closes; Tab wraps inside the dialog.
- The corner close is a 32px button named Close.
Edge cases
7 edge cases
- Right to left
- Position uses start-1/2 with an rtl correction; the close button moves to the left.
- Long unbroken description
- It overflows; the description does not break words.
- Tall content
- The panel caps at 100dvh minus 2rem and scrolls inside.
- 320px phone
- The panel is 288px wide and the content wraps.
- Opened from a menu
- Let the menu close first; the dialog portals into the Lime scope.
- Reduced motion
- The dialog appears and leaves at once.
- Forced colors
- Fill and shadow drop, so the panel edge disappears; add a transparent border.
API
6 props
DialogBase UI Root propsDialogTriggerBase UI propsDialogContent.size'sm' | 'md' | 'lg'default'md'DialogContent.showClosebooleandefaulttrueDialogContent.initialFocusBase UIDialogCloseBase UI props
Tokens
18 tokens
--raised- #ffffff
--radius-sheet- 24px
--shadow-overlay- 0 24px 48px -12px rgb(var(--shadow-ink) / 0.24), 0 4px 12px rgb(var(--shadow-ink) / 0.08)
--overlay-sm- 384px
--overlay- 480px
--overlay-lg- 640px
--scrim- rgb(15 15 13 / 0.5)
--text-xl- 22px
--weight-semibold- 600
--tracking-tight- -0.01em
--text-sm- 14px
--fg-2- #4a4943
--dur-slow- 280ms
--dur-base- 200ms
--dur-fast- 140ms
--ease-out- cubic-bezier(0.16, 1, 0.3, 1)
--ease-in- cubic-bezier(0.4, 0, 1, 1)
--scale-enter- 0.97