Modal
Overview
A modal interrupts the current workflow and focuses the user's attention on a specific task or piece of information. It sits above a dark overlay that dims the rest of the interface and blocks interaction with the page behind it.
Sandbox
Anatomy
Standard modal
- Overlay — Full-viewport scrim that dims the page behind the modal and prevents interaction with anything beneath it.
- Container — The white elevated surface; floats centered above the overlay.
- Header — 56px top region containing the leading icon, title, and dismiss button.
- Leading icon (optional) — 24×24px colored badge with a contextual icon; sits left of the title.
- Title — Semibold label that names the modal's purpose.
- Dismiss button — Icon button fixed to the top-right corner; always present.
- Content slot — The body area between the header and footer; accepts any content.
- CTA footer — Bottom action bar with a subtle background tint; holds all action buttons.
- Button group — One to three buttons anchored left in the footer; always leads with a primary button.
- Cancel button — Flat button anchored right in the footer; always present.
Confirmation modal
- Overlay — Same full-viewport scrim as above.
- Container — Same elevated surface and shadow.
- Dismiss button — Icon button in the top-right corner; always present.
- Illustration — Centered icon or badge image at the top of the body.
- Title — Centered semibold heading.
- Body text — Centered supporting copy; one short line.
- Action — Single flat button ("Close" or equivalent); centered below the body text.
Variants
Standard modal — padded body
The default for 80–90% of modal interactions. The content slot has 48px left/right padding, 16px top, and 36px bottom. The 48px horizontal value is intentional: it aligns body content with the left edge of the title text, accounting for the leading icon width and gap. The header, button layout, and dismiss behavior are all the same as described in the Anatomy section.
Use for: rapid registration, creating estimate templates, adding new products, or any task built around a form or structured input.
[Screenshot: Standard padded modal — new product creation form with leading icon, padded body, primary + secondary + cancel buttons]
Standard modal — full bleed
The same structure as the padded variant, but the content slot has no padding. The body content fills edge to edge. Use only for immersive, canvas-style workflows where the content needs to occupy the full modal surface. The automations workflow is the primary example — it's a near-viewport-sized modal that functions like an inline page.
Full-bleed modals should be rare. If the content could work with padding, use the padded variant.
[Screenshot: Full-bleed modal — automations workflow filling the near-full viewport]
Confirmation modal
A lighter-weight modal for double opt-in confirmations and non-destructive success states. There is no traditional header with icon and title row. Instead, an illustration or badge is centered at the top, followed by a heading and one short line of body copy. A single flat action button sits below. A dismiss button still appears in the top-right corner.
This covers the remaining 5–10% of modal use. Two sub-contexts to be aware of:
Destructive confirmation — Use when the user is about to do something irreversible ("Delete this record?"). The action button should use the destructive button style, not primary.
Success / acknowledgment — Use when a background action has completed and you want the user to know before continuing ("Successfully submitted!"). A single flat "Close" is the appropriate action.
[Screenshot: Confirmation modal — success state after form submission with centered illustration, heading, body, and Close button]
[Screenshot: Confirmation modal — delete confirmation with destructive action button]
Usage
Use a modal when the user needs to complete a focused task before returning to what they were doing. Modals demand the user's full attention, so reserve them for interactions that genuinely justify the interruption.
- Use the padded standard modal for any task built around form input: creating or editing records, filling out registration forms, configuring templates. This should cover the large majority of modal interactions in the EMR.
- Use the full-bleed standard modal only when the content requires a large canvas. The automations workflow is the main example. If you're reaching for full-bleed without a comparable level of complexity, reconsider.
- Use the confirmation modal for two-step destructive confirmations and for surfacing success states after a background task completes. Keep the body copy tight — one heading, one sentence, one action.
- Don't use a modal for passive information that doesn't require user action or acknowledgment. Use a toast or inline alert instead.
- Don't open a modal from inside another modal.
Best Practices
| Do | Don't |
|---|---|
| Use one primary button in the footer; add secondary or tertiary actions only when needed | Don't add more than three buttons to the button group |
| Keep the modal title short and task-specific | Don't write the title as a full sentence or instruction |
| Use the padded variant for all standard form-based flows | Don't reach for full-bleed unless the content genuinely needs edge-to-edge real estate |
| Use a destructive button style for delete confirmations | Don't use a primary button to confirm a destructive action |
| Keep confirmation modal copy to one heading and one short line | Don't put a form or multiple competing actions in a confirmation modal |
| Always include Cancel or Close so the user can exit without committing | Don't leave the overlay as the only escape route |
Accessibility
- Set
role="dialog"andaria-modal="true"on the container element. - Use
aria-labelledbypointing to the modal title so screen readers announce the dialog's purpose on open. - Move focus into the modal when it opens. The dismiss button or the first focusable element in the content slot are both valid targets.
- Trap focus inside the modal while it is open. Tab and Shift+Tab must cycle only through elements inside the container.
- Pressing Escape closes the modal and returns focus to the element that triggered it.
- The dismiss (×) button must carry an accessible label:
aria-label="Close". - Mark the overlay with
aria-hidden="true"so it is not exposed to the accessibility tree.