Operable · Level A · 2.1.2
No Keyboard Trap
Once keyboard focus lands inside any part of a page — a widget, an embedded frame, a custom component — it always has to be possible to move focus back out using only the keyboard. If exiting needs something other than standard keys (Tab, Esc, arrow keys), the user has to be told how, in advance.
- Blind
- Motor
How to recognize it
Tab into every interactive region of a page using only the keyboard and try to Tab or Esc back out of each one. A trap looks like this: focus lands inside an embedded widget, a date picker, or a custom component, and Tab just keeps cycling within it forever, with no visible way out and no announced alternative key combination. This is a total blocker for anyone who navigates by keyboard alone — blind screen reader users and people with motor disabilities who can't use a mouse — since once they're stuck, there's no way forward or backward through the rest of the page at all. A modal dialog that deliberately keeps focus contained while it's open is not a trap by itself, as long as a standard key (typically Esc) closes it and returns focus to where it came from.
How to fix it
Make sure every custom component, embedded frame, or third-party widget lets focus leave it using Tab, Shift+Tab, or Esc — the keys someone would try without being told anything special. If a component genuinely needs an unconventional way to exit, tell the user about it up front, before they get stuck, not after. Test any custom-built interactive component by tabbing all the way through the page with the mouse unplugged, literally or figuratively, and confirming you never get stuck anywhere.
Example
Avoid
<!-- custom widget captures Tab internally with no escape route and no instructions -->
<div id="custom-picker" tabindex="0" onkeydown="trapFocusForever(event)"></div>Prefer
<!-- modal dialog: Tab cycles inside while open, Esc closes it and returns focus to the trigger -->
<div role="dialog" aria-modal="true" onkeydown="if (event.key === 'Escape') closeDialog()"></div>