Components · Messaging
Basic Modal
A dialog that takes over the page for a focused task. Content is slotted, so a product can put whatever the task needs inside a consistent frame.
Figma source: Basic Modal ↗Examples
Add related output
<div class="cds-lightbox">
<div class="cds-modal" role="dialog" aria-modal="true" aria-labelledby="modal-title">
<div class="cds-modal__header">
<h2 class="cds-modal__title" id="modal-title">Add related output</h2>
<button type="button" class="cds-modal__close" aria-label="Close dialog">✕</button>
</div>
<div class="cds-modal__body">…</div>
<div class="cds-modal__footer">
<button type="button" class="cds-button cds-button--secondary">Cancel</button>
<button type="button" class="cds-button cds-button--primary">Add output</button>
</div>
</div>
</div>The demo is staged inside a bounded box so the page stays usable. In a product the lightbox covers the viewport. Focus is trapped inside the dialog while it is open — Tab through it and see.
Figma properties
| Property | Values | Notes |
|---|---|---|
Modal Slot | slot | The content area. Build product-specific content as its own Figma component and swap it in. |
Header Icon? | boolean | An icon beside the title. |
Third Button? | boolean | A third action in the footer. |
Nested Component? | boolean | Whether the slot holds a nested component. |
Instance | instance swap | The swapped content. |
Padding, from the annotations: 24px on the sides, 16px top and bottom for the content area, adjustable per usage. The guidance for the slot is also explicit: “For product-specific modals, create needed content areas as a Figma component for the slot” — extend by composition, not by detaching.
Usage
When to use it
- Use for a self-contained task that needs the user’s full attention — adding a record, editing one field set.
- Give it a title that names the task.
- Put the confirming action on the right, cancel to its left.
- Keep it short enough not to scroll; if it scrolls a lot, it should be a page.
When not to use it
- Do not use a modal for a long or multi-step form — use a page.
- Do not open a modal from a modal.
- Do not use one merely to show information — a Banner Alert or an inline section is less disruptive.
- Do not lose the user’s input if they dismiss accidentally.
One artboard is labelled “BAD EXAMPLE!! Full page coverage, incorrect tabindex — SHOULD JUST BE NEW PAGE”.
It is the right diagnosis. A dialog covering the whole viewport has stopped being a dialog: there is no context left behind it to return to, so the lightbox and the focus trap are doing nothing except breaking the back button and the page title. If the content fills the screen, it is a page — give it a URL, a heading and a breadcrumb.
Accessibility
role="dialog"witharia-modal="true", labelled by its title viaaria-labelledby.- Trap focus. Tab and Shift+Tab cycle within the dialog and cannot reach the page behind it.
- On open, move focus to the dialog — the first field, or the heading. On close, return it to the control that opened it.
- Escape closes. Clicking the lightbox closes a dismissible dialog; it must not close one holding unsaved input without warning.
- Content behind the dialog should be inert, not merely covered.
Tokens consumed
| Token | Applied to | Resolves to |
|---|---|---|
--container-background | Dialog surface | --color-white |
--container-border | Header and footer rules | --color-gray-300 |
--type-section-heading-* | Title | 20 / 28 / Bold |
| Lightbox | Overlay | --color-black at 25% — the Figma spec |