PatternsUpdated April 27, 2026

Overlays Pattern

Choose the right overlay (Dropdown, Dialog, Sheet) with production UX rules and accessible defaults.

PatternsOverlays

OverviewLink to section

Overlays are not just UI components.

They define how users interact with actions, decisions, and workflows.

Choosing the wrong overlay leads to:

  • broken flows
  • poor accessibility
  • confusion in user intent
  • inconsistent product behavior

Choosing the right one makes interactions feel fast, clear, and intentional.

Mental model

Overlays are interaction contracts, not visual components.

Decision matrixLink to section

OverlayBest forAvoid when
DropdownMenuQuick contextual actions (row actions, small choices)Forms, confirmations, long content
DialogFocused task that blocks the page (create, edit, confirm)Long workflows, navigation panels
SheetSide workflows (filters, panels, mobile nav)Destructive confirmations, small binary actions

Rule of thumbLink to section

  • Dropdown → micro actions
  • Dialog → focused task
  • Sheet → side workflow

Core UX rulesLink to section

Focus & keyboardLink to section

  • Trap focus in Dialog and Sheet
  • Restore focus to trigger on close
  • Support Escape to close safely
  • Ensure full keyboard navigation

Scroll behaviorLink to section

  • Lock page scroll when Dialog/Sheet is open
  • Allow scrolling inside the overlay
  • Avoid double scroll containers

LayeringLink to section

  • Avoid deep nesting (Dropdown → Dialog is acceptable, keep rare)
  • Ensure overlays stack correctly (z-index / portals)

Closing behaviorLink to section

  • Always provide explicit actions: Cancel / Save
  • Do not auto-close on error
  • Require confirmation for destructive actions

Common flowsLink to section

Create flow → DialogLink to section

Use Dialog when the user starts a task and must complete or cancel it.


Filters / side workflow → SheetLink to section

Use Sheet for progressive disclosure.


Row actions → DropdownLink to section

Use DropdownMenu for contextual actions.

Tip: destructive actions should open a confirmation Dialog.

Accessibility checklistLink to section

Before shipping overlays:

  • Dialog / Sheet has a visible or accessible title
  • Focus is trapped correctly
  • Focus returns to trigger on close
  • Escape closes safely
  • Buttons have clear labels
  • Icon-only triggers include aria-label
  • Dropdown items are keyboard accessible

Production rule

Accessibility is not optional for overlays. It defines whether the interaction is usable at all.

ExamplesLink to section

create-dialog.tsx
<Dialog>
  <DialogTrigger asChild>
    <Button>Create</Button>
  </DialogTrigger>

  <DialogContent>
    <DialogHeader>
      <DialogTitle>Create project</DialogTitle>
      <DialogDescription>
        Give it a name and status.
      </DialogDescription>
    </DialogHeader>
    {/* form */}
  </DialogContent>
</Dialog>
filters-sheet.tsx
<Sheet>
  <SheetTrigger asChild>
    <Button variant="outline">Filters</Button>
  </SheetTrigger>

  <SheetContent>
    <SheetHeader>
      <SheetTitle>Filters</SheetTitle>
      <SheetDescription>
        Narrow results and apply advanced options.
      </SheetDescription>
    </SheetHeader>
    {/* filters */}
  </SheetContent>
</Sheet>

Decision guideLink to section

Use this pattern if:

  • users need contextual actions
  • workflows require focus or blocking
  • navigation or filters need progressive disclosure
  • accessibility and keyboard navigation matter

Avoid misuse when:

  • a simple inline action is enough
  • overlays replace clear page structure
  • multiple overlays stack unnecessarily

Prefer

  • one overlay per interaction
  • clear user intent
  • accessible focus handling
  • progressive disclosure

Avoid

  • stacking multiple overlays
  • using Dialog for navigation
  • using Dropdown for forms
  • implicit destructive actions

Why this mattersLink to section

Overlays are where interaction quality becomes visible.

A good overlay system makes your product feel:

  • faster
  • safer
  • clearer
  • more deliberate

A bad one makes everything feel fragile.