WCAG 2.1.2
No Keyboard Trap
10.3%
of the 609 sites we scanned fail this
Ranging from 1.9% of US healthcare providers to 52% of Shopify DTC stores. Pooled across five targeted cohorts, so treat it as a convenience sample rather than a rate for the web.
What it means and how to fix it
What 2.1.2 covers
- We detect this: Focus cycles that cannot be escaped with Tab or Shift+TabConfirmed by actually pressing the key rather than inferred from markup, then flagged for human confirmation because auto-focus widgets and animations can imitate a trap.
- We detect this: Third-party embeds that swallow focus and never return itAttributed to the embedding page, since that is where the fix has to go: a skip link before the iframe.
- We detect this: Dialogs that hold focus deliberately and can be dismissedExcluded as conformant. A modal keeping focus while open is correct behaviour, not a trap.
- No engine can detect this: Traps that only appear after a specific sequence of interactionsWe probe the page as loaded. A trap three steps into a checkout needs the journey walked.
Of that, one failure is detectable automatically, and these are what the rates on this page measure. Each needs its own fix. The percentage is the share of all 609 scanned sites affected. These do not sum to the 10.3% above: a site can fail more than one of them, and most that fail any fail several.
- The keyboard gets stuck on an element10.3%
A keyboard trap prevents users from tabbing past an element, stranding keyboard-only users on part of the page.
What it looks like in code
JavaScript// Tab is swallowed and focus is forced back to the start, with no way out
dialog.addEventListener("keydown", (e) => {
if (e.key === "Tab") {
e.preventDefault();
firstControl.focus();
}
});dialog.addEventListener("keydown", (e) => {
if (e.key === "Escape") return close();
if (e.key !== "Tab") return;
// Cycle inside the dialog while it is open, but Escape always leaves
const atEnd = document.activeElement === lastControl && !e.shiftKey;
const atStart = document.activeElement === firstControl && e.shiftKey;
if (atEnd) { e.preventDefault(); firstControl.focus(); }
if (atStart) { e.preventDefault(); lastControl.focus(); }
});Holding focus inside an open dialog is correct. What makes it a trap is having no exit: the criterion is satisfied as soon as a standard key, normally Escape, releases it.
Shown for The keyboard gets stuck on an element. Both halves are written rather than harvested: this failure lives in JavaScript rather than in the markup, so there is no page element to show.
For what the criterion formally requires, read the W3C Understanding document.
How often it fails
Share of scanned sites in each cohort. These are five targeted studies, not a random sample of the web, so read the contrast between cohorts rather than any one figure as a web-wide rate.
Who fails it most3 cuts by CMS vendor, population tier, country
By CMS vendor
By population tier
By country
Groups smaller than 8 sites are not shown: a rate over a handful of sites moves by tens of points on a single result.
What the numbers do not say
The CMS pattern that runs through this corpus shows up here too, though less sharply: 5 of 20 Drupal city sites carry a suspected keyboard trap, against 0 of 32 on CivicPlus. Traps come from custom interactive code, and a platform that ships its own menu and dialog components leaves less room for it than one assembled per site.
What this does not measureLimits of these figures, and where the corpus came from
- Some of these figures come from detectors that flag candidates rather than confirmed failures (keyboard-trap), because the patterns they look for have legitimate exceptions. Treat them as an upper bound on confirmed failures.
- These are five targeted cohorts, not a random sample of the web. Per-cohort rates are the figure to quote; the pooled rate is a convenience sample.
- Denominators count sites that produced a result. Sites that were blocked or errored are excluded rather than counted as passing.
- Occurrence counts are floors: the engine records at most 25 occurrences of a rule per page.
- The EU and Indian cohorts retained only the primary success criterion per finding, so a rule mapping to several criteria contributes to one of them in those two cohorts and to all of them in the other three.
| Cohort | Scanned | Attempted |
|---|---|---|
| Shopify DTC stores | 75 | 75 |
| US local government | 158 | 221 |
| US healthcare providers | 208 | 218 |
| EU e-commerce | 107 | 170 |
| Indian financial services | 61 | 72 |
Corpus generated 2026-09-18.
Check your own site
A free scan reports WCAG 2.1.2 alongside everything else, with the exact elements that fail.
Run a free scan
