2.1.1 Keyboard

WCAG 2.2 · 2.1.1 A Operable

What it requires

All functionality of the content must be operable through a keyboard interface, without requiring specific timings for individual keystrokes. If a person can do something with a mouse, pointer, or gesture, they must also be able to do it using only the keyboard. The criterion allows one exception: functionality that inherently depends on the path of the user's movement and not just its endpoints — for example, free-hand drawing — need not be keyboard-operable, though an alternative is still encouraged.

"Keyboard interface" is broad: it covers physical keyboards, on-screen keyboards, and switch devices or speech software that emulate keystrokes. Meeting 2.1.1 is also what makes most assistive technologies work, since they drive the page through the same keyboard interface.

  • People who cannot use a mouse — due to motor disabilities, tremor, or limited fine motor control — and navigate entirely by keyboard.
  • Blind and low-vision screen reader users, who operate the page with keystrokes rather than pointing.
  • Switch, sip-and-puff, and voice-control users, whose devices emulate the keyboard.
  • Power users and anyone on a device where the pointer is temporarily unavailable.

How to detect it

Concrete checks for keyboard operability
Check How Tooling
Reach everything Tab and Shift+Tab through the page; every link, button, control, menu, and custom widget must receive focus. Manual
Activate everything Operate each control with Enter, Space, and arrow keys as appropriate; nothing should be mouse-only. Manual
Custom widgets Check that div/span elements wired with click handlers are also keyboard-operable and focusable. Manual + screen reader
Hover-only content Confirm menus, tooltips, and pop-ups that open on hover also open and dismiss via keyboard. Manual
Automated scan Catches some signals (e.g. positive tabindex, click handlers without keyboard handlers), but cannot confirm full operability. axe, partial

How to fix it

  1. Use native interactive elements (<a href>, <button>, <input>) — they are focusable and keyboard-operable for free.
  2. If you must build a custom control, give it role, tabindex="0", and key handlers (Enter/Space to activate, arrows where a pattern expects them).
  3. Never rely on mouseover/click alone; pair pointer events with keyboard events or focus events.
  4. Avoid positive tabindex values; keep the DOM order logical instead.
  5. Test the whole flow with the mouse unplugged before shipping.

Prefer a real button over a scripted div:

<!-- Keyboard-operable for free -->
<button type="button" class="menu-toggle" aria-expanded="false">
  Menu
</button>

Copy-paste tests

Automated coverage

These axe-core rules flag failures of this criterion: frame-focusable-content, scrollable-region-focusable, and server-side-image-map. Run them via the axe DevTools browser extension or axe-core in CI. Automated tools only catch some keyboard failures, so always pair them with manual testing.

Run this in the browser console

console-2-1-1.js
// Read-only: surfaces likely keyboard problems for review.
// Click handlers on non-interactive, non-focusable nodes:
const suspects = [...document.querySelectorAll('[onclick], div, span')]
  .filter(el => (el.onclick || el.getAttribute('onclick')) &&
    !el.matches('a[href],button,input,select,textarea') &&
    el.tabIndex < 0);

// Positive tabindex (breaks natural order):
const positives = [...document.querySelectorAll('[tabindex]')]
  .filter(el => el.tabIndex > 0);

console.table([...suspects, ...positives].map(el => ({
  tag: el.tagName, tabindex: el.tabIndex,
  text: (el.textContent || '').trim().slice(0, 40)
})));
suspects.forEach(el => el.style.outline = '2px solid red');
positives.forEach(el => el.style.outline = '2px solid orange');

What to check manually: Tab through the whole page with no mouse — every control must be reachable and operable with Enter, Space, and arrow keys; and confirm focus is never trapped where Tab/Shift+Tab can't move on. No script can verify either.