UX Design

Keyboard Navigation for Non-Mouse Users

By EZUD Published · Updated

Keyboard Navigation for Non-Mouse Users

Every interactive element on a web page must be reachable and operable with a keyboard alone. This is not optional polish — it is WCAG 2.2 Success Criterion 2.1.1 (Level A), the lowest tier of compliance. Keyboard access supports blind users navigating with screen readers, motor-impaired users operating switch devices or sip-and-puff controllers, power users who prefer keyboard shortcuts, and anyone with a temporarily injured hand.

Why Keyboard Navigation Breaks

Keyboard access fails when developers build custom components without considering non-mouse input. The most common causes:

  • Custom controls without native semantics. A <div> styled as a button receives no keyboard focus and fires no events from Enter or Space. Use <button> instead.
  • Mouse-only event handlers. onClick without corresponding onKeyDown handling. Hover-triggered menus with no focus equivalent.
  • Invisible or removed focus indicators. CSS resets that include outline: none without a replacement style. See color contrast standards for focus indicator visibility requirements.
  • Focus traps without an exit. Modal dialogs that capture focus but offer no keyboard mechanism to close.
  • Illogical tab order. Using tabindex values greater than 0, which overrides the natural DOM order and creates unpredictable navigation sequences.

Essential Keyboard Interactions

Every web user should be able to perform these actions with a keyboard:

ActionKey(s)Notes
Move to next focusable elementTabForward through DOM order
Move to previous elementShift + TabBackward through DOM order
Activate a buttonEnter or SpaceBoth should work
Follow a linkEnterSpace should not activate links
Toggle a checkboxSpaceNot Enter
Select a radio buttonArrow keysWithin a radio group
Open a dropdownEnter, Space, or Down ArrowPlatform conventions vary
Close a dialogEscapeReturn focus to trigger element
Navigate tabs/menusArrow keysWithin composite widgets

Building Keyboard-Accessible Components

Use Native HTML Elements

Native <button>, <a>, <input>, <select>, and <textarea> elements receive keyboard focus and handle key events automatically. Every custom widget built from <div> or <span> requires you to manually add tabindex="0", role, keyboard event handlers, and ARIA states. The effort is almost never worth it — use native elements.

Manage Focus in Dynamic Content

When content changes without a full page load — modals opening, accordion panels expanding, single-page app route changes — focus must move to the new content. Otherwise, keyboard users remain stranded at their previous position in the DOM.

Practical patterns:

  • Modal opens: Move focus to the first focusable element inside the modal. Trap focus within the modal until it closes. On close, return focus to the element that triggered the modal.
  • Inline content expands: Move focus to the newly revealed content, or to the heading of the expanded section.
  • SPA route change: Move focus to the main content area or page heading of the new view. See focus management in SPAs for detailed implementation strategies.

A user who must tab through a 50-item navigation menu on every page load will abandon your site. Provide a “Skip to main content” link as the first focusable element. It can be visually hidden until focused:

.skip-link {
  position: absolute;
  left: -9999px;
}
.skip-link:focus {
  position: static;
  left: auto;
}

Focus Indicators

WCAG 2.2 SC 2.4.13 (Focus Appearance, Level AA) requires that focus indicators have:

  • An area at least as large as a 2px solid perimeter around the component.
  • A 3:1 contrast ratio between the focused and unfocused states.

Never remove the default browser outline without providing a custom replacement that meets these requirements. A common pattern:

:focus-visible {
  outline: 2px solid #1a73e8;
  outline-offset: 2px;
}

The :focus-visible pseudo-class ensures the indicator appears for keyboard navigation but not for mouse clicks, addressing the visual design concern without sacrificing accessibility.

Tab Order

The DOM order should match the visual order. If CSS repositions elements (using float, flex order, grid placement, or position), the visual layout may diverge from the tab sequence, confusing keyboard users.

Rules:

  • Never use tabindex values greater than 0. They create a separate priority layer that overrides DOM order and becomes unmaintainable.
  • Use tabindex="0" only when adding focus to a non-interactive element that genuinely needs it (rare).
  • Use tabindex="-1" to make an element programmatically focusable (via JavaScript focus()) without adding it to the tab sequence.

Testing Keyboard Navigation

  1. Unplug your mouse (or disable your trackpad) and attempt to complete every user flow.
  2. Watch for: Elements you cannot reach. Focus indicators that disappear. Focus that jumps to unexpected locations. Traps you cannot escape.
  3. Test with screen readers: NVDA (free, Windows), VoiceOver (built into macOS/iOS), TalkBack (Android). Keyboard behavior and screen reader behavior are closely linked but not identical. Review our screen reader compatibility guide.
  4. Automate what you can: axe-core detects missing focus indicators, non-focusable interactive elements, and tabindex misuse. See accessibility testing tools.

Key Takeaways

  • Keyboard access is a Level A requirement — the absolute baseline for WCAG compliance.
  • Native HTML elements provide keyboard support for free; custom widgets require significant manual effort.
  • Focus must follow content changes: modals, expanded sections, SPA route transitions.
  • Never remove focus outlines without providing a replacement that meets WCAG 2.2 focus appearance criteria.
  • Test by unplugging the mouse and completing every user flow.

Next Steps

Sources

Keyboard interaction patterns referenced from the W3C WAI-ARIA Authoring Practices Guide (APG) and WebAIM keyboard accessibility guidelines.