A dialog should take focus on open and return it on close
Aliases: focus trap · restore focus · modal focus
What it is
When a dialog, drawer, or menu opens and the keyboard and screen reader stay on the page underneath, people type into a layer they cannot see. Open should hand focus in; close should hand it back to the control that opened it. That is dialog focus handoff. The issue is entering and leaving a layer, not whether a full page should autofocus on load, and not an async script stealing focus mid-keystroke.
Why it happens
A modal visually cuts off the page beneath. If focus does not follow, a keyboard user keeps tabbing through invisible underlying controls, and the screen reader still speaks the floor. Handing in usually lands on the dialog title or the first operable control, then cycles inside (a focus trap) so escape to the floor is blocked. On close, if focus falls to the document start or body, people lose “where I was” and must re-find the trigger. Returning to the trigger makes the round trip a reversible location memory. A non-modal panel should not trap, but should still receive focus on open and return it on close, or opening did not happen for the keyboard.
Studying it
Open a dialog from the keyboard; check whether focus enters, whether Tab is confined, whether Esc restore lands on the trigger. Factors: initial focus on title versus first field, presence of a trap, close animation dropping focus. Outcomes: escapes to the floor, time to re-find the trigger after close. A screen reader should hear the dialog’s name. Walk established dialog focus patterns; the measure is whether the round trip is reversible, not an attribute checklist.
Where it stops holding
Toasts and brief notices should not take focus, or the word being typed is yanked away—that is a different “do not steal” rule. A full-screen routed “dialog” is really a new page; close should use history, not restore a trigger that has been unmounted. Nested dialogs should restore to the previous layer, not jump to the original trigger in one hop. Touch has no Tab-trap problem, but after close the scroll position and trigger should still be in the viewport.
Applying it
- On open, move focus into the layer (title or first field) and cycle inside until close.
- On close, return focus to the trigger; if it is gone, to a sensible nearby control that is scrolled into view.
- Let a screen reader hear the layer’s name; do not move focus without an accessible name.
- Verify by tabbing into a dialog, walking a loop that must not fall through, and Escaping onto the original button. Then check that a screen reader announced the layer’s name on open.
Related
- Within the group: E2.22.1 Focusing on load interrupts a screen reader’s document order · E2.22.2 Autofocus fits a single, obvious primary field · E2.22.4 A focus jump nobody asked for interrupts typing in progress
- Adjacent: E4.10 Modal dialogs · E4.09 Drawers
- Search terms:
dialog focus handoff·focus trap·restore focus