The Keyboard Trap: A Bug That Locks Users In
A keyboard trap is a place on your page that focus can enter but never leave, and it ends the visit for anyone not using a mouse.
Most bugs degrade an experience. A keyboard trap ends it. It’s one of the few defects on the web that doesn’t just make a page worse but makes it impossible, and I find it interesting because of how completely invisible it is to the people who create it.
Here’s what it is. Some users navigate entirely with a keyboard: they press Tab to move focus from one interactive element to the next, Shift-Tab to move backward, Enter or Space to activate things. This includes blind users driving a screen reader, people with motor impairments who can’t manage precise pointing, power users who find it faster, and anyone whose trackpad just died. For all of them, the Tab key is the mouse. A keyboard trap is a spot on the page where focus can get in but can’t get out. You Tab into a widget, and then Tab doesn’t advance, Shift-Tab doesn’t retreat, Escape does nothing. The rest of the page still exists, visibly, inches away, and you cannot reach it. The only exit is closing the tab. For a mouse user the page is fine. For a keyboard user it has a hole in the floor.
The classic offenders are embedded things: third-party chat widgets, cookie consent panels, video players, date pickers, and above all modals. Modals deserve special attention because they involve a deliberate, correct kind of trapping that goes wrong in both directions. When a modal dialog is open, focus should be contained inside it, because Tabbing to the obscured page behind a dialog is confusing, especially for a screen reader user who can’t see that the background is dimmed. So developers write a focus trap on purpose. The bug comes in two flavors. Either the trap is missing, and focus wanders out of the dialog into a page the user can’t see properly, or the trap is present but there’s no keyboard way to close the dialog, no Escape handler, no reachable close button, and the intentional trap becomes a permanent one. The accessibility standard’s rule is simple and worth stating plainly: if you can move focus into a component with the keyboard, you must be able to move it out with the keyboard, and if the exit is anything unusual, you have to tell the user what it is.
Why does this keep happening in an era of mature frameworks? Because the way we build components hides the problem. A developer assembles a page from packages: a carousel from one, a chat bubble from another, a date input from a third. Each was tested by its author, usually with a mouse, in isolation. Keyboard behavior is an emergent property of the whole page, of the interaction between the browser’s native focus order and every script that manipulates it. Nobody owns it. And custom widgets built from divs are worse than no widget at all, because a div isn’t focusable or operable until someone writes the code to make it so, and it’s easy to write the entering half and forget the leaving half. The browser’s built-in elements, links, buttons, selects, never trap you. Traps are always handmade.
The other reason is that the test that would catch it is one nobody runs. Developers test by looking and clicking. A keyboard trap is undetectable that way. The test is almost embarrassingly cheap: put the mouse out of reach and Tab through the entire page, top to bottom, watching where the focus indicator goes. Can you see focus at every step? Does it move in an order that matches the visual layout? Can you open every menu, every modal, every picker, and, crucially, get back out? Ten minutes, no tools, and it finds not just traps but their milder cousins: focus that disappears into invisible elements, focus that jumps to the top of the page after a modal closes, focus indicators suppressed by some CSS reset that shipped with outline set to none.
What makes the trap a business problem and not just a technical one is where it tends to live. Traps congregate in exactly the components that sit closest to money: the consent banner in front of everything, the login modal, the date picker in the booking flow, the payment form in its iframe. A trap on the pricing page doesn’t lose you a pageview. It loses you the customer at the moment of highest intent, and it loses them in a way no analytics funnel will ever explain, because the session just ends.
Automated scanners, including the checks GazeSite runs, can flag the conditions where traps breed: focusable elements with no visible focus style, custom widgets missing keyboard handlers, dialogs without close semantics. But the definitive test remains the human one, and I’d argue every founder should perform it once on their own checkout. Unplug the mouse. Try to buy your own product. If you can’t get out of some widget, you’ve just felt, for one frustrating minute, what some of your customers feel every time. They don’t file bugs. They leave. The Tab key is the cheapest usability lab you will ever own.
More articles
The few words next to a button often decide the click, because that is where the visitor's last doubts live.
Read →A signup wall placed before the visitor has seen any value trades most of your audience for a list of half-committed emails.
Read →Vague praise gets skipped; specific stories get read, because specificity is the only part of a testimonial a skeptic can't fake in their head.
Read →