BlogIf You Can't Tab Through It, You Can Be Sued For ItScan · Site Quality

If You Can't Tab Through It, You Can Be Sued For It

DO
Dana Okafor · November 2025 · 9 min read

TL;DR

Pick up your hands off the mouse and try to use your own site with only the Tab, Enter, Space, and arrow keys. If you get stuck in a modal, can't reach the menu, or lose track of where focus is, you have shipped a WCAG Level A failure that screen-reader users, keyboard-only users, and switch-device users hit every visit. Keyboard operability is SC 2.1.1 (Keyboard) and SC 2.1.2 (No Keyboard Trap), both Level A, both mandatory under ADA Title III, Section 508, EN 301 549, and the European Accessibility Act. A focus trap in a cookie banner or a custom dropdown is one of the most reliable findings in an accessibility complaint.

The test that takes two minutes and fails most sites

There is no faster accessibility diagnostic than the keyboard pass. Load your most important flow, sign-up, checkout, search, and put the mouse away entirely. Use only Tab (forward), Shift+Tab (back), Enter/Space (activate), Esc (dismiss), and arrow keys (within widgets). Watch for three things: can you reach every interactive element, can you tell where focus currently is, and can you always get back out of whatever you tabbed into.

Most sites fail at least one. The custom dropdown that only opens on click. The modal that lets you tab in but not out. The carousel that swallows your focus and arrow keys forever. The "skip to content" link that does not exist, forcing keyboard users through 40 nav links on every page. These are not theoretical, they are the lived experience of a meaningful share of users, and they are exactly the defects that turn up in litigation findings because they are reproducible on demand.

Keyboard operability is not a niche. It is the shared foundation for screen-reader users (who navigate via keyboard), motor-impaired users who cannot use a mouse, switch-device and sip-and-puff users, and a large population of power users who simply prefer the keyboard. When keyboard access breaks, all of those groups break at once, and a tester can demonstrate it in a single recorded session.

SC 2.1.1: everything must be reachable and operable

WCAG Success Criterion 2.1.1 Keyboard (Level A) is simple to state: all functionality must be operable through a keyboard interface, without requiring specific timings for individual keystrokes. If a sighted mouse user can do it, a keyboard user must be able to do it too. The most common ways teams violate it:

  • Non-semantic interactive elements. A <div onclick> styled to look like a button is not focusable or operable by keyboard. Native <button> and <a> are focusable and key-activatable for free; div-buttons are not.
  • Mouse-only event handlers. Menus that open on mouseover with no keyboard equivalent, drag-and-drop with no keyboard alternative, hover-reveal content unreachable by Tab.
  • Removed focus. The infamous outline: none with no replacement, the element is reachable but you cannot see where you are, which is its own failure (SC 2.4.7 Focus Visible).
  • Positive tabindex. tabindex="3" and friends create a bizarre, brittle tab order that almost never matches the visual order. The only valid values in practice are 0 (in natural order) and -1 (focusable only programmatically).
<!-- WRONG: a div pretending to be a button -->
<div class="btn" onclick="submit()">Submit</div>
<!-- Not focusable, not Enter/Space-activatable, no role. -->

<!-- RIGHT: the native element does all of it for free -->
<button type="submit">Submit</button>

<!-- If you MUST use a non-button, you owe all the behavior: -->
<div role="button" tabindex="0"
     onclick="submit()"
     onkeydown="if(event.key==='Enter'||event.key===' ')submit()">
  Submit
</div>
<!-- ...which is why you should just use <button>. -->

SC 2.1.2: the keyboard trap is the classic finding

WCAG Success Criterion 2.1.2 No Keyboard Trap (Level A) says: if keyboard focus can move to a component, it must be able to move away using only the keyboard. A keyboard trap is when you tab into something and cannot get out, your Tab key cycles forever inside a widget, or Esc does nothing, and a mouse-free user is simply stuck on that part of the page with no way to proceed.

Traps are catastrophic because they do not just block one feature, they block the entire rest of the page. A keyboard user who hits a trap in your cookie consent banner literally cannot reach your content. As the TestParty 2025 guide to SC 2.1.2 notes, the most common sources are improperly built modals, custom date pickers, embedded media players, and third-party widgets that manage their own focus badly.

The cruel irony: the correct fix for a modal, trapping focus inside it while it is open, is what creates the trap when implemented wrong. A modal SHOULD keep focus within itself so a keyboard user does not tab into the inert page behind it. But it MUST release that focus the moment the modal closes (via Esc, the close button, or completing the action), and return focus to the element that opened it.

// A modal that traps focus correctly AND releases it
function openModal(modal, opener) {
  const focusable = modal.querySelectorAll(
    'a[href], button:not([disabled]), input, select, textarea, [tabindex]:not([tabindex="-1"])'
  );
  const first = focusable[0], last = focusable[focusable.length - 1];
  first.focus();

  function onKey(e) {
    if (e.key === 'Escape') return closeModal(modal, opener);
    if (e.key !== 'Tab') return;
    // Cycle focus WITHIN the modal while open...
    if (e.shiftKey && document.activeElement === first) {
      e.preventDefault(); last.focus();
    } else if (!e.shiftKey && document.activeElement === last) {
      e.preventDefault(); first.focus();
    }
  }
  modal.addEventListener('keydown', onKey);
  modal._cleanup = () => modal.removeEventListener('keydown', onKey);
}

function closeModal(modal, opener) {
  modal.hidden = true;
  modal._cleanup && modal._cleanup();  // release the trap
  opener.focus();                       // return focus to the trigger
}

Why automated scans are necessary but not sufficient here

Contrast and missing alt text are fully machine-detectable. Keyboard operability is partly detectable and partly not, which is exactly why it is so persistent. A scanner can reliably flag the structural precursors: divs with click handlers and no role/tabindex, positive tabindex values, removed focus outlines, missing skip links, interactive elements that never receive focus. Those catches are valuable and should gate CI.

But whether a modal actually traps, whether the tab order is logical, whether focus returns correctly after an action, these require executing the page and observing focus movement, ideally with a real keyboard pass. The right program combines both: an automated scan to catch the structural red flags continuously, plus a scripted keyboard walk of critical flows.

# Automate the keyboard walk of a critical flow with Playwright
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    page = p.chromium.launch().new_page()
    page.goto(url + '/checkout')

    seen, prev = set(), None
    for _ in range(60):                  # bounded: detect a trap
        page.keyboard.press('Tab')
        el = page.evaluate('''() => {
            const a = document.activeElement;
            return a ? a.tagName + '#' + (a.id||'') + '.' + (a.className||'') : null;
        }''')
        if el == prev:                   # focus did not move = TRAP
            print('KEYBOARD TRAP at:', el); break
        if el in seen:                   # cycled back = end of order
            print('Tab order length OK:', len(seen)); break
        seen.add(el); prev = el
    # Also assert: a visible focus indicator exists at each stop.
Add a skip link first. A single "Skip to main content" link as the first focusable element is the highest-leverage keyboard fix: it lets keyboard users bypass repeated navigation on every page (SC 2.4.1). It is a few lines of HTML and CSS and it dramatically improves the experience for everyone who tabs.

Focus management is the hard part

Reaching elements is the easy half of keyboard accessibility. The half that separates a usable site from a frustrating one is focus management, controlling where focus goes when the page changes underneath the user. Single-page applications make this acute, because navigating "to a new page" does not actually reload anything; without intervention, focus stays wherever it was, and a screen-reader user has no idea the content changed.

  • Route changes in SPAs. When a client-side route changes, move focus to the new view's heading (or a dedicated focus target) and announce it, so keyboard and screen-reader users know they navigated. Leaving focus stranded on the clicked link is a silent, pervasive failure in framework apps.
  • Dynamically revealed content. When an accordion expands, a "load more" appends results, or an inline form error appears, focus must be managed so the user encounters the new content rather than tabbing past invisible-to-them changes. Error summaries should receive focus on submit so the user lands on what they must fix.
  • Disappearing focus targets. If the element holding focus is removed (a closed menu item, a deleted row), focus defaults to <body> and the user is dumped to the top of the document. Always move focus to a sensible sibling or container before removing the focused element.
  • Focus order vs. visual order. CSS (flexbox order, grid placement, absolute positioning) can make the DOM order diverge from the visual order, so a keyboard user tabs in a sequence that does not match what they see (SC 2.4.3 Focus Order). The DOM order should match the logical reading order.

None of this is caught by a "can every element receive focus" check. It requires reasoning about the page over time, what happens to focus when state changes, which is why focus management is both the most common real-world keyboard failure and the one most likely to survive an automated-scan-only program.

The bottom line

If you cannot Tab through it, a meaningful share of your users cannot use it, and you can be sued for it. Keyboard operability rests on two Level A criteria: everything must be reachable and operable by keyboard (2.1.1), and nothing may trap focus (2.1.2). Both are mandatory under the ADA, Section 508, EN 301 549, and the EAA, and keyboard traps are among the most reproducible findings in accessibility litigation because a tester can demonstrate them in one recorded session. Scan for the structural red flags continuously, run a scripted keyboard walk of your critical flows, build modals that trap-then-release correctly, and ship a skip link today. Then put the mouse down and test it yourself.

Find the Gaps Before They Cost You

Scan audits your site for the accessibility, performance, AEO, and security gaps that quietly drain revenue and invite lawsuits, in one pass.

Try Scan Free →
Dana Okafor Dana Okafor writes about AI quality engineering at alt.qa, built by TheWorkCompany.