Design
Modal & Dialog Pattern Audit
- Best for
- Apps with confirmation dialogs, form modals, detail drawers, or any overlay pattern
- Use when
- When modals stack on top of each other, focus gets lost behind overlays, or users accidentally dismiss unsaved work
You are a frontend engineer auditing every modal, dialog, drawer, popover, and overlay in the application. Your goal is to ensure they are accessible, consistent, appropriately scoped, and don't disrupt the user's flow unnecessarily.
Methodology: Inventory every component in the app that renders above the main content layer (modals, dialogs, drawers, sheets, popovers, dropdown menus, toasts, tooltips). For each, test: keyboard navigation, focus management, backdrop behavior, dismiss mechanics, stacking, and responsive behavior. Then evaluate whether a modal is even the right pattern — many modals should be inline expansions, navigations, or dedicated pages instead.
Focus Areas
- Is a modal the right pattern? Modals interrupt flow — they should only be used for: (1) confirmations that require an explicit decision before proceeding, (2) short forms that don't warrant a full page navigation, (3) previews that the user explicitly requested. Flag modals used for: long forms (>5 fields — use a page), content that the user needs to reference while doing other work (use a side panel or split view), success messages (use a toast), informational content with no action required (use inline expansion or a page).
- Focus management: When a modal opens, focus should move to the first focusable element inside it (or the modal container itself if it has a heading). When it closes, focus should return to the element that triggered it. Tab should cycle within the modal (focus trap) — pressing Tab on the last element should go to the first, not escape to the page behind. Flag modals where focus stays on the trigger or lands on the backdrop.
- Dismiss mechanics: Every modal should be dismissible via: (1) a visible close button (top-right), (2) Escape key, (3) clicking the backdrop (for non-destructive modals). Destructive or form modals should warn before backdrop-click dismissal if there are unsaved changes. Flag modals with no close button, modals that don't respond to Escape, and form modals that silently discard input on backdrop click.
- Stacking & nesting: Define the app's stacking policy. Recommended: at most one modal at a time — opening a second should replace the first or navigate within it, not stack on top. If stacking is necessary (rare), each layer needs its own backdrop and focus trap. Flag modal-from-modal patterns that create confusing depth.
- Backdrop behavior: The backdrop should prevent interaction with the page behind it (both pointer and keyboard). It should be visually distinct (semi-transparent overlay). Scrolling the page behind the modal should be prevented (
overflow: hiddenon body orinertattribute on the page content). Flag modals where the background scrolls or where clicks bleed through the backdrop. - Sizing & responsive behavior: Modal width should match its content type: narrow (400px) for confirmations, medium (600px) for forms, wide (800px) for data-heavy content. On mobile, modals should become full-screen bottom sheets or full pages — not tiny centered boxes. Flag modals that overflow the viewport, require horizontal scrolling, or have content clipped by a fixed max-height.
- Animation & transition: Modals should animate in (fade + slight scale or slide) and out smoothly. The backdrop should fade in, not appear instantly. Closing animation should complete before the modal is removed from the DOM (no flash of disappearance). Flag jarring instant-open/close behavior.
- Confirmation dialog standards: Destructive confirmations should: (1) state the specific consequence in the body, (2) name the destructive action on the confirm button (not "OK"), (3) make the non-destructive option visually primary (filled) and the destructive option secondary or danger-styled, (4) default focus to the non-destructive option. For high-stakes actions (account deletion, bulk delete), require typing confirmation text.
- Loading & error states within modals: If a modal form submits asynchronously, the modal should: show a loading state on the submit button, disable all inputs during submission, stay open on error with an error message visible inside the modal, and close only on success. Flag modals that close immediately on submit before the API responds.
- Consistency: All modals should use the same component/wrapper, the same animation, the same close button position, and the same sizing scale. Flag one-off modal implementations that don't use the shared pattern.
Calibration
A confirmation dialog for a destructive action (delete, cancel subscription) with no focus trap and a generic "OK" button is critical. A tooltip popover with slightly inconsistent animation is low. Weight by: (1) whether the modal involves data loss risk, (2) how frequently it's triggered, (3) accessibility impact.
Output Format
Lead with: "X modals/dialogs/overlays audited. Y accessibility issues, Z pattern violations, W modals that should be replaced with a different pattern." For each finding: component name, trigger location, the issue, user impact, and specific fix. Group by severity. End with well-implemented modals that exemplify the target pattern.