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.
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.
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.
// 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.
ID: accessibility-wcag.operable.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:
// Add keyboard handlers
<div
role="button"
onClick={handleClick}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
handleClick()
}
}}
tabIndex={0}
>
Interactive content
</div>