Keyboard And Focus

Raw
GuidancelatestWCAG 2.2 (October 2023)Retrieved 2026-05-12

Keyboard Operability and Focus — WCAG 2.2

Source: www.w3.org/TR/WCAG22/ §2.1.1, §2.1.2, §2.4.7, §2.4.11


Quick reference

CriterionRequirementLevel
2.1.1All functionality operable by keyboardA
2.1.2No keyboard trap — focus can always leaveA
2.4.7Focus indicator is visibleAA
2.4.11Focused component is not entirely hidden (New in 2.2)AA

2.1.1 Keyboard — Level A

All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes.

Exception: Underlying functions that depend on the path of movement (not just endpoints), such as freehand drawing or signature capture.

Implementation notes:

  • Every interactive element — buttons, links, form fields, custom controls — must be reachable and operable by keyboard
  • Required keyboard patterns by role (from ARIA APG):
    • Button: Enter or Space to activate
    • Link: Enter to activate
    • Checkbox: Space to toggle
    • Radio group: arrow keys to move between options
    • Modal dialog: Tab/Shift+Tab within dialog; Escape to close
    • Menu: arrow keys to navigate; Escape to close; Enter/Space to select
    • Tab panel: arrow keys between tabs; Tab enters panel content
  • Custom components built with div or span must add tabindex="0" and keyboard event handlers
  • Drag-and-drop interactions must have a keyboard alternative

2.1.2 No Keyboard Trap — Level A

If keyboard focus can be moved to a component using a keyboard, then focus can be moved away using only the keyboard. If non-standard exit keys are required, the user must be informed of the method.

Note: This criterion applies to the entire page — any component that traps keyboard focus breaks the page for keyboard users, regardless of other conformance. It is listed as a non-interference requirement in WCAG conformance section 5.2.

Implementation notes:

  • Modal dialogs: trap focus within the dialog (correct behavior), but must release on close. Trapping focus in a dialog is intentional and correct — what 2.1.2 forbids is making it impossible to close.
  • Rich text editors, custom date pickers, embedded widgets: ensure Escape exits or provide clear instructions
  • iframes: focus must not become permanently stuck — user must be able to tab out
  • Test with keyboard only: Tab through the entire page and confirm you can reach and leave every interactive element

2.4.7 Focus Visible — Level AA

Any keyboard-operable user interface has a mode of operation where the keyboard focus indicator is visible.

Implementation notes:

  • Never use outline: none or outline: 0 on focused elements without providing an alternative visible focus style
  • Browser default focus outlines satisfy this criterion — removing them without replacement is the most common violation
  • Acceptable alternative focus styles: custom outline, box-shadow ring, border change, background-color change — anything that makes the focused state visually distinct
  • The criterion requires a mode where focus is visible — most implementations satisfy this by making focus always visible. Some implementations show focus only for keyboard navigation (:focus-visible CSS pseudo-class) — this is acceptable.

CSS pattern — custom focus ring:

:focus-visible {
  outline: 2px solid #005fcc;
  outline-offset: 2px;
}

Do not:

/* Never do this without replacement */
* { outline: none; }
button:focus { outline: none; }

2.4.11 Focus Not Obscured (Minimum) — Level AA (New in WCAG 2.2)

When a UI component receives keyboard focus, the component is not entirely hidden due to author-created content.

What this means:

  • Sticky headers, cookie banners, fixed navigation bars, and chat widgets must not completely obscure the focused element
  • Partial obscuration is permitted at AA — the focused element just cannot be entirely covered
  • Full non-obscuration (no part hidden) is required at AAA (2.4.12 — not covered here)

Implementation notes:

  • Use scroll-margin-top or scroll-padding-top on the page or scroll container to account for sticky header height when focus causes scrolling
  • Fixed banners at the bottom of the viewport: ensure elements near the bottom of the content area have enough scroll-margin-bottom
  • scroll-margin-top: 80px (where 80px matches the sticky header height) is the standard fix
  • Test by tabbing through a page with a sticky header and confirming no focused element is fully hidden
/* Accommodate sticky header (80px tall) */
html {
  scroll-padding-top: 88px; /* header + 8px buffer */
}