Repository navigation
Web HIG tip #13: Keep focus inside the dialog #29
frozonfreak
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Open a modal on your site, the cookie settings, a confirm step, or a sign-in box, and press Tab a few times. If the focus ring disappears behind the dark overlay and lands on a link in the page underneath, a keyboard user is now working in a part of the page they can't see.
Web HIG tip #13 (Quick #73 / HIG-A11Y-008): Modals must trap focus inside and restore focus to the trigger on close.
Why it matters
A modal says "deal with this first". Focus has to agree with what the screen shows:
The full HIG covers this in §5.3, Keyboard Focus & Interaction. HIG-A11Y-008 (Modal focus containment, severity error) asks for three things: focus moves into the dialog when it opens, Tab and Shift+Tab cycle within it while it's active, and focus returns to the control that opened it when it closes. The spec is explicit that
aria-modal="true"tells assistive technology the dialog is modal but does not itself create a focus trap. The keyboard pattern table adds that Escape closes a dialog. On the WCAG side, this supports 2.4.3 Focus Order (Level A). A trap with no way out would fail 2.1.2 No Keyboard Trap (Level A), so the Escape key and a visible close button are part of the rule, not extras.The rule of thumb
Ask: while the dialog is open, can Tab ever reach something behind it? And when it closes, am I back where I started?
The native
<dialog>element, opened withshowModal(), does most of the work:showModal()makes the rest of the page inert, so Tab can't reach it, moves focus into the dialog, and closes it on Escape. Modern browsers also return focus to the element that was focused before the dialog opened. Test that in the browsers you support rather than assuming it. Tab can still move into the browser's own controls, such as the address bar. That's expected: the rule is about the page behind the dialog.Do this instead
<dialog>withshowModal()over a custom<div role="dialog">. If you have to keep a custom modal, setinerton the page content behind it, move focus in yourself, and handle Escapearia-modal="true"alone. It changes what assistive technology is told, not where Tab goesshow()or a popover for non-modal UI. A dialog that doesn't block the page shouldn't trap focus eitherQuick check for your app
Open a dialog on example.com using only the keyboard. Check that focus lands inside it. Press Tab and Shift+Tab ten times each: focus should stay in the dialog and never land on the page behind the overlay. Press Escape: the dialog should close and focus should be back on the button you opened it with. Repeat with a screen reader and with your confirm, sign-in, and cookie dialogs. A tool can tell you a dialog has
aria-modal, but only tabbing through shows whether focus actually stays put.The Web HIG is an open set of guidelines for how the web should behave, not a component library. Design systems define how it looks. The Web HIG defines how it behaves.
All reactions