WCAG 2.1.1 Keyboard — Testing Guide
WCAG 2.1.1 Keyboard (Level A) requires that all functionality of the content is operable through a keyboard interface. For users with motor impairments who cannot use a mouse or touchscreen, keyboard
WCAG 2.1.1 Keyboard (Level A) requires that all functionality of the content is operable through a keyboard interface. For users with motor impairments who cannot use a mouse or touchscreen, keyboard is the primary interaction method. Mobile screen-reader users also navigate with keyboard-like gestures.
What it requires
Every interactive element — buttons, links, form controls, custom components — must be:
- Reachable via Tab / Shift+Tab
- Activatable via Enter or Space
- Usable without requiring specific timing (except where essential)
No mouse-only operation. No touch-only operation. Every feature needs a keyboard path.
Common violations
1. Div with onClick
<div onclick="doSomething()">Click me</div>
Not focusable, not keyboard-activatable.
Fix:
<button onclick="doSomething()">Click me</button>
<!-- or -->
<div role="button" tabindex="0" onclick="doSomething()"
onkeydown="if(event.key==='Enter') doSomething()">Click me</div>
2. Custom dropdowns
Custom select / menu without keyboard support. User can open but not navigate options.
Fix: Implement WAI-ARIA combobox / menu pattern. Arrow keys navigate, Enter selects, Escape closes.
3. Modal dialogs without focus trap
Modal opens; Tab goes past its content into the background page. User loses track.
Fix: Focus trap — cycle Tab within modal. Return focus to trigger on close.
4. Drag-and-drop without keyboard alternative
Reorder-list with drag. Keyboard users cannot reorder.
Fix: Alternative: buttons to move up / down. Or keyboard shortcuts (Space to pick up, Arrow to move).
5. Hover-only menus
Menu appears on hover. Keyboard users cannot trigger.
Fix: Also appears on focus. Open with Enter / Space.
6. Canvas / WebGL content
Game or interactive visualization with mouse-only input.
Fix: Keyboard equivalents. Arrow keys for movement, Space for action. Or ALT text + alternative interface.
Testing
Manual
- Unplug your mouse
- Use only Tab, Shift+Tab, Enter, Space, Arrow keys, Escape
- Try to complete every flow in the app
- Note any element you cannot reach or activate
This is the gold-standard test. Nothing replaces it.
Automated
- axe-core has
focus-order-semanticsandtabindexchecks - Lighthouse accessibility audit
- Cypress / Playwright can simulate keyboard, assert focus
cy.get('body').tab(); // cypress-plugin-tab
cy.focused().should('have.attr', 'data-test', 'next-element');
iOS
External Bluetooth keyboard. Full Access enabled in iOS Settings. Navigate entire app with keyboard.
Android
External Bluetooth keyboard. Test with TalkBack + keyboard for double-coverage.
Fix patterns
Native HTML / UI controls first
, , all have keyboard support baked in. Use them before building custom.
When custom is necessary, follow ARIA patterns
WAI-ARIA Authoring Practices has patterns for combobox, menubar, tabs, accordions, sliders. Each with required keyboard interactions.
Focus management
- Modal opens → focus first interactive
- Modal closes → focus returns to trigger
- Error on submit → focus moves to error / first invalid
- Route change → focus moves to top or page heading
Keyboard shortcuts
If your app has keyboard shortcuts, ensure:
- User can discover them (help dialog)
- They do not override browser / OS defaults (no Ctrl-W for "close tab" re-use)
- They are rebindable for users with accessibility needs
Mobile considerations
Mobile screen readers (VoiceOver, TalkBack) simulate keyboard-like navigation through gestures. 2.1.1 still applies:
- Every element reachable
- Every element activatable
- Focus order makes sense
Test with screen reader on mobile, not just with external keyboard.
How SUSA tests keyboard
For web, SUSA drives Tab-based navigation through interactive elements. Flags:
- Elements that cannot receive focus
- Elements focused but not activatable
- Focus traps (infinite loop)
- Missing focus indicators (also violates 2.4.7)
susatest-agent test https://myapp.com --persona accessibility_user
For native, SUSA checks focusable and clickable attributes, detects custom views without accessibility delegates.
Specific keys
- Tab: move focus forward
- Shift+Tab: move focus backward
- Enter: activate button / link / submit
- Space: activate button / toggle / scroll
- Arrows: navigate within composite widgets (menus, tabs, sliders, tree)
- Home / End: first / last item in composite
- Escape: cancel / close modal
Follow convention. Surprising keyboard behavior is worse than none.
Anti-patterns
tabindex > 0: breaks natural order, creates confusiontabindex="-1"on interactive: reachable by script, not by Tab — bad UX- Custom widget without keyboard support: disables whole class of users
- Focus lost after action: user at top of page with no indication
Keyboard access is foundational. Without it, features are not available to every user.
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