# Keyboard accessibility is fully supported

- **Pattern:** `ab-000110` (`accessibility-wcag.operable.keyboard-accessible`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000110
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000110)

## Why it matters

Keyboard accessibility is the baseline for all assistive technology: screen readers, switch access devices, voice control, and eye-tracking all depend on the keyboard interaction model. WCAG 2.2 SC 2.1.1 (Keyboard) is Level A — every function reachable by mouse must have a keyboard equivalent. Mouse-only interactions like hover menus, drag-and-drop without alternative, or right-click context menus completely lock out users who cannot use a pointing device.

## Severity rationale

Medium because mouse-only interactions create functional exclusions for keyboard users — a WCAG 2.2 SC 2.1.1 Level A violation — though severity is bounded by how many features are affected.

## Remediation

Audit every interactive element for keyboard operability. Hover-only menus must open on focus; drag-and-drop must have a keyboard alternative; custom widgets must handle Enter and Space.

```tsx
// Hover menu — also opens on keyboard focus
<div
  onMouseEnter={() => setOpen(true)}
  onFocus={() => setOpen(true)}
  onMouseLeave={() => setOpen(false)}
  onBlur={(e) => {
    // Close only when focus leaves the entire menu subtree
    if (!e.currentTarget.contains(e.relatedTarget)) setOpen(false)
  }}
>
  <button aria-expanded={isOpen} aria-haspopup="true">Products</button>
  {isOpen && <ul role="menu">{/* items */}</ul>}
</div>
```

For drag-and-drop, provide buttons that move items up/down as a keyboard-accessible alternative. Tab through the entire app to confirm every interactive element is reachable.

## Detection

- **ID:** `keyboard-accessible`
- **Severity:** `medium`
- **What to look for:** Enumerate every relevant item. Keyboard-navigate through the entire application. Verify that every interactive element is reachable and operable via keyboard (Tab, Enter, Space, Arrow keys). Check for mouse-only interactions like drag-and-drop, right-click menus, or hover-only content.
- **Pass criteria:** At least 1 of the following conditions is met. All functionality is operable via keyboard. No mouse-only interactions. Every interactive element is reachable via Tab key.
- **Fail criteria:** Some functionality requires mouse interaction and has no keyboard equivalent.
- **Skip (N/A) when:** Never — keyboard accessibility applies to all projects.
- **Detail on fail:** Example: `"Drag-and-drop file upload has no keyboard alternative. Hover-only menu appears on mouse hover but not on keyboard focus"`
- **Remediation:** Ensure all interactions have keyboard equivalents:

  ```tsx
  // Add keyboard handlers
  <div
    role="button"
    onClick={handleClick}
    onKeyDown={(e) => {
      if (e.key === 'Enter' || e.key === ' ') {
        e.preventDefault()
        handleClick()
      }
    }}
    tabIndex={0}
  >
    Interactive content
  </div>
  ```

## External references

- wcag 2.1.1
- section-508 407.6

Taxons: accessibility

HTML version: https://auditbuffet.com/patterns/ab-000110
