use UI

Modal Dialog

Also called dialog, popup, lightbox, overlay window

A window layered over the page that blocks interaction with everything behind it until it is dismissed.

Example

Try it with the keyboard: open it, press Tab a few times, then Escape. Focus starts in the field, never leaves the dialog, and returns to the button when it closes.

When to use it

  • A decision genuinely blocks progress — deleting something, discarding unsaved work, confirming a payment.
  • The task is short enough to finish in one go: a few fields, a choice, a confirmation.
  • The content behind would only distract, and losing sight of it costs the user nothing.
  • You need certainty that the user saw it. Nothing else in the interface interrupts this reliably.

When not to

  • The content is long or needs scrolling. A modal that scrolls internally on a small screen is worse than a page.
  • The user needs the page behind for reference — comparing values, copying a name, checking a total. Use a drawer or popover instead.
  • It happens often. An interruption that fires forty times a day stops registering and starts irritating.
  • You are about to open a modal from a modal. Stacked layers destroy any sense of where you are and where back leads.
  • It is only an announcement. A toast or a banner says the same thing without taking the interface hostage.

Trade-offs

  • Guarantees attention — nothing else can be touched until it is handled.
  • Keeps the user in place; no navigation, no lost scroll position.
  • Well-defined semantics and browser support, including the native dialog element.
  • It is an interruption, and interruptions cost goodwill when overused.
  • Cramped on small screens, where a full page or bottom sheet usually fits better.
  • Easy to implement badly: leaking focus, unclosable by keyboard, or losing scroll position underneath.

Accessibility

What this pattern needs in order to work for everyone.

Keyboard
  • Escape must close it. This is not optional — it is the first thing a keyboard user tries.
  • Tab must cycle within the dialog and never reach the page behind it.
  • Move focus to the dialog on open — the heading or the first control, not the close button, which invites accidental dismissal.
  • Return focus to the element that opened it on close, or the user is dropped back at the top of the page.
Roles and state
  • Use `role="dialog"` with `aria-modal="true"`, or the native `<dialog>` element which handles both.
  • Label it with `aria-labelledby` pointing at the heading; a dialog announced as just “dialog” tells nobody anything.
  • Content behind should be inert — the `inert` attribute or `aria-hidden` — so a screen reader cannot wander into it.
Focus
The trap is the defining behaviour: focus enters on open, stays inside while it is up, and returns to the trigger on close. Losing any of these turns it into a visual-only modal that keyboard users can walk straight through.

In the wild

  • GitHub Repository deletion asks you to type the name inside a modal — a genuinely blocking, irreversible decision.
  • Figma Keeps modals for account-level actions and uses panels for anything that needs the canvas visible.

Compared with

Side-by-side breakdowns of patterns that solve a similar problem.

Related tools