DEV Community

Devanshu Biswas
Devanshu Biswas

Posted on

A Modal Dialog Done Right: Focus Trap, Esc, Scroll Lock

A modal isn't just a centered box with a dark backdrop. Get it wrong and it's an accessibility trap — keyboard users get stuck, screen readers wander off, the page scrolls behind it. Here's one done right, from scratch.

🪟 Try it (Tab around, hit Esc): https://dev48v.infy.uk/design/day20-modal-dialog.html

The five things a real modal does

  1. Opens over a dimmed backdrop with a fade/scale-in.
  2. Closes on ×, backdrop click, AND Escape — all three.
  3. Traps focus — Tab/Shift+Tab cycle within the dialog; you can't tab out to the page behind it.
  4. Locks body scroll (and compensates for the scrollbar shift so the page doesn't jump).
  5. Returns focus to the trigger button on close — don't strand the user.

Plus the ARIA: role="dialog", aria-modal="true", aria-labelledby pointing at the title.

The focus trap

Query the dialog's focusable elements; on Tab from the last one, wrap to the first; on Shift+Tab from the first, wrap to the last. That's the whole trick.

The shortcut

The native <dialog> element + .showModal() gives you focus trap, Esc, backdrop, and ::backdrop for free. Reach for it first; hand-roll only when you need full control.

🔨 Full build (overlay → open/close → Esc+backdrop → focus trap → scroll lock + return focus) on the page: https://dev48v.infy.uk/design/day20-modal-dialog.html

Part of DesignFromZero. 🌐 https://dev48v.infy.uk

Top comments (0)