WCAG 2.1.2 No Keyboard Trap — Testing Guide for Mobile & Web Apps

WCAG 2.1.2, "No Keyboard Trap," is a Level A success criterion designed to prevent users who rely solely on keyboard navigation from becoming stuck within an interactive element. This means that once

January 01, 2026 · 6 min read · WCAG Guides

Ensuring Keyboard Accessibility: A Practical Guide to WCAG 2.1.2

WCAG 2.1.2, "No Keyboard Trap," is a Level A success criterion designed to prevent users who rely solely on keyboard navigation from becoming stuck within an interactive element. This means that once a user navigates into a component using a keyboard, they must be able to navigate *out* of it using only the keyboard.

What WCAG 2.1.2 Requires

In straightforward terms, this means: if a user can reach an element on your website or in your application using the Tab key (or equivalent keyboard navigation), they must also be able to move away from that element using the same keyboard commands. They should never reach a point where they can enter a section, dialog, or component, but have no way to exit it without using a mouse.

Why Keyboard Traps Matter

Keyboard traps disproportionately affect users with motor disabilities who cannot use a mouse, as well as users with visual impairments who may be using screen readers that emulate keyboard navigation. It also impacts users who temporarily cannot use a mouse due to injury or environmental constraints.

Real User Impact:

Common Violations and Examples

Keyboard traps often manifest in interactive UI components.

#### Web Applications

  1. Modal Dialogs Without Esc Key or Tab Out: A modal appears, and the focus is trapped within its content. Users can tab between elements inside the modal, but tabbing stops there. There's no visible "close" button reachable via tab, or the "Esc" key doesn't dismiss it.
  1. Custom Select Menus: A custom-built dropdown or select list is implemented where tabbing into the list of options allows navigation within the options, but tabbing again doesn't move focus *out* of the select component itself.
  1. Complex Widgets with Nested Interactive Elements: Widgets like date pickers or rich text editors might contain internal navigation (e.g., arrows for day selection in a date picker) that, if not handled correctly, can trap focus within the widget's internal controls.

#### Mobile Applications (Android/iOS)

While mobile apps primarily use touch, keyboard navigation is still relevant for accessibility features like external keyboards or switch access.

  1. Dialogs/Alerts Without Dismiss Action: A native or custom dialog appears, and focus is set to its content. If there's no clear "OK" or "Cancel" button accessible via keyboard navigation, or if the dialog doesn't automatically dismiss when focus leaves it (if appropriate), users can get stuck.
  1. Custom Tabbed Interfaces or Accordions: Similar to web, custom components that expand or switch content sections can trap focus if the navigation out of the expanded section isn't correctly implemented for keyboard users.

How to Test for Compliance

Testing for keyboard traps requires a systematic approach.

#### Manual Testing Steps

  1. Identify Interactive Elements: Locate all buttons, links, form fields, custom controls, modals, and any other element that receives focus.
  2. Tab Forward: Start at the beginning of the page or screen and repeatedly press the Tab key. Observe the focus indicator.
  3. Enter Interactive Components: Navigate into any component that appears interactive (e.g., a modal, a dropdown, an expandable panel).
  4. Tab Within and Attempt to Exit: Once inside a component, try tabbing through its internal interactive elements. Then, attempt to tab *past* the last interactive element of that component.
  1. Test with Shift+Tab: Perform the same tests using Shift + Tab to ensure you can also navigate backward out of components.
  2. Test "Esc" Key (for Modals/Dialogs): For modals and dialogs, specifically test if pressing the Esc key dismisses them. This is a common and expected way to exit such components.
  3. Test with Screen Reader (Optional but Recommended): Use a screen reader (like NVDA, JAWS, VoiceOver) to simulate a keyboard-only user experience more accurately.

#### Automated Tools

While manual testing is crucial for nuanced interactions, automated tools can flag potential issues.

#### Mobile-Specific Considerations

How to Fix Violations

Fixing keyboard traps generally involves ensuring proper focus management.

#### Web Applications

  1. Modal Dialogs:

    // Example using JavaScript for focus management on modal open/close
    const modal = document.getElementById('myModal');
    const firstFocusable = modal.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
    const lastFocusable = modal.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"]):last-child'); // Simplified, requires more robust selection

    function openModal() {
        modal.style.display = 'block';
        firstFocusable.focus();
        // Add event listener for Esc key
        document.addEventListener('keydown', handleEscKey);
        // Add event listeners for trapping focus
        modal.addEventListener('keydown', handleTabKey);
    }

    function closeModal() {
        modal.style.display = 'none';
        // Return focus to the element that opened the modal (store this reference)
        document.removeEventListener('keydown', handleEscKey);
        modal.removeEventListener('keydown', handleTabKey);
    }

    function handleEscKey(event) {
        if (event.key === 'Escape') {
            closeModal();
        }
    }

    function handleTabKey(event) {
        if (event.key === 'Tab') {
            if (event.shiftKey) { // Shift+Tab
                if (document.activeElement === firstFocusable) {
                    event.preventDefault();
                    lastFocusable.focus();
                }
            } else { // Tab
                if (document.activeElement === lastFocusable) {
                    event.preventDefault();
                    firstFocusable.focus();
                }
            }
        }
    }
  1. Custom Controls: Ensure that the tabindex attribute is used correctly. tabindex="0" makes an element focusable and part of the natural tab order. tabindex="-1" makes an element programmatically focusable but not part of the tab order. Ensure that after interacting with a custom control, the focus can move logically to the next element.

#### Mobile Applications

How SUSA Checks This Criterion

SUSA autonomously explores your application, mimicking real user behavior across various personas. During its exploration, SUSA:

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free