Modal
A dialog overlay that focuses user attention on a task or decision. Use when an action requires explicit user confirmation. Don't use for non-critical information that can be shown inline — use Alert instead.
FigmaDescription
Modal interrupts the user's current flow to present a task, decision, or critical information that must be addressed before continuing.
Confirmation dialogs ("Delete this project?"), short data-entry forms, destructive action warnings, and content previews that don't warrant a full page.
Some actions require deliberate confirmation rather than immediate execution. Modal creates a bounded context where the user's full attention is on a single decision, then returns them to where they were.
Not for routine feedback — if no decision is required, use Alert instead. If the message is a system-level notification, use Notification Modal.
Anatomy
| Part | Required? | Notes |
|---|---|---|
| Backdrop | Required | Semi-transparent overlay behind the modal. Clicking it dismisses the modal unless the action is destructive or data entry is in progress. |
| Header | Required | Contains the modal title. Must be linked to the dialog via aria-labelledby. |
| Body content | Required | The main content. Keep it focused — modals are not a canvas for complex layouts. |
| Close button | Required | × button in the header. Always present unless the action is a required confirmation with no dismissal path. |
| Secondary action | Conditional | Cancel, Go back, or an alternative action. Omit when the close button already serves this role. |
| Primary action | Required | The main call to action. Use a destructive button style for irreversible actions. |
Variants
Confirmation
Asking the user to confirm an action before it executes. "Publish this consultation?" Always provide a clear Cancel path.
Destructive confirmation
The action cannot be undone. Delete, remove, archive. Use a destructive/danger button style for the primary action. State explicitly what will be deleted.
Form
Short forms that logically belong in context with the triggering page. Keep them brief — if the form grows complex, use a full page instead.
Informational
Displaying content that needs focused reading — terms, previews, help content. Use sparingly; consider whether a page or drawer would serve better.
Usage guidelines
When to use
- Confirming an irreversible or high-consequence action.
- Collecting a small, self-contained piece of input that doesn't warrant navigating away.
- Displaying content that requires focused attention and explicit dismissal.
When not to use
- For feedback after an action — use Alert.
- For complex forms or multi-step flows — use a page or wizard pattern.
- As an entry point for navigation — don't open modals from within modals.
- For low-stakes confirmations — avoid over-confirming routine actions. Reserve modals for genuinely important decisions.
Do / Don't
Do
Write modal titles as plain questions or statements: "Delete this project?" or "Export stakeholder data". Not "Confirmation Required".
Don't
Don't nest modals. If a modal action opens another modal, the flow needs redesigning.
Do
For destructive actions, make the consequence explicit: "This will permanently delete 47 responses and cannot be undone."
Don't
Don't make "Cancel" the primary button. The primary action should always be the most likely next step.
Layout & Spacing
Modals are centred horizontally and vertically in the viewport. They have a maximum width and scroll internally when content overflows — the backdrop and modal chrome stay fixed.
| Element | Spec |
|---|---|
| Default width | 540px max, 90vw on small screens |
| Max height | 85vh — body scrolls internally beyond this |
| Header padding | --op-space-20 all sides |
| Body padding | --op-space-20 horizontal, --op-space-16 vertical |
| Footer padding | --op-space-16 all sides |
| Border radius | --op-radius-lg |
| Backdrop opacity | 60% |
| Backdrop colour | --op-color-bg-overlay |
| Element | Token |
|---|---|
| Background | --op-color-bg-primary |
| Header/footer border | --op-color-border-default |
| Title text | --op-color-text-primary, --op-text-lg, font-weight: 600 |
| Body text | --op-color-text-primary, --op-text-sm |
Engineering notes
- The native
<dialog>element traps focus automatically when opened withshowModal(). Custom implementations must implement a focus trap manually — focus should cycle through interactive elements within the modal and not reach page content behind it. - Always return focus to the element that triggered the modal on close. Without this, keyboard users lose their position in the page.
- Don't use
display: noneto hide modals — use thehiddenattribute or thedialogelement's open state so screen readers don't read hidden content. - Avoid opening modals on page load. They interrupt users before they have context and are a common cause of accessibility failures in form-heavy applications.
Keyboard interaction
| Key | Action |
|---|---|
| Tab | Moves focus forward through interactive elements within the modal. Focus is trapped — it does not leave the modal. |
| Shift + Tab | Moves focus backward through interactive elements within the modal. |
| Escape | Closes the modal and returns focus to the triggering element. Always implement this unless the modal requires a mandatory decision. |
| Enter or Space | Activates the focused button. |
Why it matters
Focus management is the most commonly failed accessibility requirement in modals. When a modal opens, focus must move into it — otherwise keyboard and screen reader users are stranded on the page behind it. When it closes, focus must return to the trigger — otherwise users lose their place. Both are required for a modal to be genuinely accessible.
ARIA
| Role or attribute | When to use | Example |
|---|---|---|
| ||
| ||
| ||
|
How to apply it
When a modal opens, move focus to the modal container or to the first interactive element inside it — whichever gives the most useful context. For confirmation modals, focusing the container first means the title and description are announced before anything is activated. For form modals, focusing the first input is often more efficient.
Things to avoid
- Don't allow focus to leave the modal while it's open. Page content must not be reachable via Tab.
- Don't remove the modal from the DOM while it's open with animation — this can confuse screen readers. Animate out, then remove.
- Don't use
role="alertdialog"unless the modal is communicating a critical error that demands immediate attention. For confirmations and forms,role="dialog"is correct. - Don't auto-close modals on a timer. Users may need more time to read or act.