figma guide
Designing modals and dialogs in Figma: overlays, focus traps, and handoff
Build modal and dialog UI in Figma with scrims, size tokens, component variants, and prototype flows—plus specs engineers need for focus, dismiss, and stacking.
- Published
- Updated
- Jun 04, 2026
- Read time
- 6 min
- Level
- Intermediate
Quick answer
Modals in Figma should be a component set with variants for size (sm/md/lg/full-screen), type (dialog, alert, drawer-style sheet), and state (open default is enough for static handoff; add loading/disabled on primary actions). Structure every modal as: scrim (semi-transparent fill) → surface (card with radius + shadow) → header / body / footer with auto layout. Document dismiss rules (Esc, outside click, explicit close only) in the component description for Dev Mode. Pair with form field components inside the body, interactive button states on actions, and accessibility plugins for contrast on scrims. Browse setup and pattern guides on the Figma guides hub.
Who this is for
- Product designers shipping confirmations, paywalls, and onboarding overlays.
- Design system maintainers publishing one dialog primitive for web and mobile.
- Engineers who need clear rules for focus trap, z-index, and scroll lock—not just a pretty card.
Modal anatomy (what to include every time)
| Layer | Role | Typical spec |
|---|---|---|
| Scrim | Dims page behind modal | rgba(0,0,0,0.48)–0.64; full viewport |
| Surface | Dialog card | Radius 12–16; elevation token (shadows guide) |
| Header | Title + optional close | Min height 56–64; title left, icon button right |
| Body | Copy, forms, lists | Scroll when content exceeds max height |
| Footer | Actions | Primary right (web); stack on mobile |
| Focus ring | Keyboard visibility | Show on default button variant in design spec |
Verdict: if you only draw the white card without scrim and footer actions, handoff will miss half the production behavior.
Modal types (match the pattern to the decision)
| Type | When to use | Primary action | Dismiss |
|---|---|---|---|
| Alert | Irreversible or critical | One destructive or primary | Often explicit button only |
| Confirm | Reversible choice | Cancel + Confirm | Esc + outside click (document) |
| Form modal | Short data entry | Submit + Cancel | Validate before close |
| Full-screen sheet | Mobile-heavy flows | Back or Done | Swipe down (mobile spec) |
| Non-modal panel | Persistent tools | N/A | No scrim—use side panel pattern |
Link destructive flows to your form validation states so error text does not overflow the modal width.
Component structure (recommended)
Modal / Dialog (component set)
├── Variant: size = sm | md | lg | fullscreen
├── Variant: type = dialog | alert | sheet
└── Structure (auto layout, vertical):
├── Scrim (absolute, fill parent frame)
└── Surface (centered, max-width token)
├── Header (horizontal auto layout)
├── Body (vertical, gap token, scroll if needed)
└── Footer (horizontal, gap 12, primary aligned end)
Sizing tokens (web starting point):
| Size | Max width | Max body height | Use case |
|---|---|---|---|
| sm | 400px | 240px | Confirmations, alerts |
| md | 480–560px | 360px | Settings snippet, short forms |
| lg | 640–720px | 480px | Multi-field onboarding |
| fullscreen | 100% minus safe area | 100% | Mobile wizards |
Use layout grids on the page behind the modal so the surface aligns to your 8pt scale—not arbitrary centering.
Scrim and elevation (do not eyeball)
| Property | Recommendation | Why |
|---|---|---|
| Scrim color | Semantic overlay/scrim token | Dark mode needs different alpha (dark mode tokens) |
| Surface shadow | elevation/overlay or lg shadow | Separates from page without heavy blur |
| Border | 1px border/subtle optional | Helps on busy marketing backgrounds |
| Z-index note | In description: z-modal = 1300 (example) | Devs map to CSS layers |
Run contrast check: title and body text on the surface must pass WCAG against the card background, not the scrim.
Prototyping modals without misleading stakeholders
- Base frame: full page at target breakpoint (responsive frames).
- Overlay frame: duplicate page + place modal component instance on top; scrim covers full frame.
- Interaction: button on page → Open overlay (or navigate to overlay frame with Instant transition).
- Close: close icon → Close overlay or navigate back.
- Optional: second overlay frame for stacked dialog (rare—document as edge case).
For motion, keep transitions dissolve 200ms or instant—Figma will not replicate focus trap; note that in presenter notes. See prototype basics and animation limits.
Common mistake: prototyping modal as a separate page with no scrim—stakeholders think the underlying page is still interactive.
Accessibility and behavior spec (write this in Dev Mode)
| Behavior | What to document |
|---|---|
| Focus trap | Tab cycles inside modal until closed |
| Initial focus | First field or primary button |
| Esc key | Closes unless role=alertdialog |
| Outside click | On/off per type (confirm vs alert) |
| Scroll lock | Body scroll disabled while open |
| Return focus | Focus returns to trigger on close |
Add a small annotation layer on the handoff page listing these bullets—engineers rarely read scattered comments on the scrim.
Handoff checklist
| Deliverable | Location |
|---|---|
| Component variants | size, type, button states |
| Spacing | Auto layout gaps = spacing tokens |
| Colors | Semantic variables (color system) |
| Max height + scroll | Body frame: overflow scroll note |
| Mobile safe area | Fullscreen variant respects safe areas |
| Z-index stack | Description vs toast/banner layers |
Use Dev Mode checklist before review. For token export beyond native inspect, see dev handoff plugins.
Stacking modals and nested dialogs
| Scenario | Design guidance |
|---|---|
| Confirm on top of form modal | Second scrim slightly darker; reduce first modal opacity 50% |
| Toast while modal open | Toast above modal z-index—show in separate artboard |
| Drawer + dialog | Avoid; pick one overlay pattern per platform |
If you must show two dialogs, ship a variant stacked=true on the component description—do not duplicate unrelated frames.
Common mistakes
| Mistake | Consequence | Fix |
|---|---|---|
| No scrim | Looks like inline card | Always include dim layer |
| Modal wider than viewport | Horizontal scroll on mobile | max-width: min(560px, 100vw - 32px) in spec |
| Detached buttons | Inconsistent hover/disabled | Instance from button library |
| Long copy without scroll | Overflow hidden in dev | Set max height on body + scroll |
| Forms without error variants | Broken layout on validate | Use form error variants |
| Sharing prototype link only | Misses dismiss rules | Description + handoff artboard |
FAQ
Should the modal be a component or a frame template?
Component set if your team ships more than one dialog per quarter. Use a template frame only for marketing one-offs.
How do I show a modal on mobile in Figma?
Use fullscreen or bottom sheet variant on a 390px frame; anchor sheet to bottom with top radius 16+. Prototype with overlay, not a shrunk desktop card.
Can I use clip content instead of a scrim?
Clip content on the surface crops children—it does not dim the page. You still need a separate scrim rectangle behind the card.
Do modals belong in the team library?
Yes—same library as buttons and forms, shared tokens.
Bottom line
Treat modals as behavior + layout: scrim, sized surface, header/body/footer, and written dismiss/focus rules. Build variants for size and type, prototype with overlays, and hand off scroll and z-index explicitly. Continue with forms in Figma, sections for flow organization, and the tutorials hub.
§ Keep reading