Success Criterion 2.1.1: Keyboard
Official W3C Definition
All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes, except where the underlying function requires input that depends on the path of the user's movement and not just the endpoints.
Why This Criterion Matters
Many users cannot use a mouse and rely entirely on keyboard navigation. This includes blind users (who use screen readers), users with motor disabilities, and power users who prefer keyboard efficiency. If functionality requires a mouse, these users are completely locked out.
Who Benefits
Blind Users
Cannot see mouse pointer or screen elements to click.
Motor Disabilities
May use keyboard, switch devices, or voice control instead of mouse.
Repetitive Strain Injuries
Keyboard may be less painful than mouse use.
Power Users
Prefer keyboard shortcuts for faster navigation.
How to Meet This Criterion
Essential Keyboard Keys
| Key | Expected Behavior |
|---|---|
| Tab | Move focus to next interactive element |
| Shift+Tab | Move focus to previous interactive element |
| Enter | Activate buttons, links, submit forms |
| Space | Activate buttons, toggle checkboxes |
| Arrow Keys | Navigate within menus, sliders, radio groups |
| Escape | Close modals, cancel operations |
Technique 1: Use Native HTML Elements
<!-- Good: Native button - keyboard accessible by default -->
<button type="submit">Submit Form</button>
<!-- Good: Native link - keyboard accessible by default -->
<a href="/products">View Products</a>
<!-- Good: Native form controls -->
<input type="text" id="name">
<select id="country">...</select>
<textarea id="message"></textarea>
Technique 2: Make Custom Controls Keyboard Accessible
<!-- Good: Custom button with keyboard support -->
<div role="button"
tabindex="0"
onclick="handleClick()"
onkeydown="if(event.key === 'Enter' || event.key === ' ') handleClick()">
Custom Button
</div>
<!-- Better: Just use a real button and style it -->
<button class="custom-styled-btn" onclick="handleClick()">
Custom Button
</button>
<!-- Bad: Div without keyboard support -->
<div onclick="handleClick()">Click me</div>
<!-- Bad: Link without href (not focusable) -->
<a onclick="navigate()">Go somewhere</a>
<!-- Bad: Mouse-only event handlers -->
<span onmouseover="showMenu()">Menu</span>
<!-- Bad: Drag-only functionality with no alternative -->
<div draggable="true" ondragstart="...">Drag me</div>
Common Failures to Avoid
| Failure | Problem | Solution |
|---|---|---|
| Click-only event handlers | Keyboard users can't activate | Add keyboard event handlers or use buttons |
| Hover-only menus | Keyboard can't trigger hover | Add focus handling for menus |
| Drag-and-drop only interfaces | No keyboard alternative | Provide button-based reordering |
| Custom widgets without tabindex | Can't focus the element | Add tabindex="0" and keyboard handlers |
| Positive tabindex values | Breaks natural tab order | Use tabindex="0" and DOM order |
Testing Methods
Keyboard Testing Steps
- Put away your mouse: Navigate using only keyboard
- Tab through the page: Can you reach all interactive elements?
- Activate controls: Press Enter or Space on buttons and links
- Test menus: Can you open, navigate, and close menus?
- Test forms: Can you fill out and submit forms?
- Test modals: Can you open, use, and close dialogs?
- Test custom widgets: Sliders, date pickers, etc.
Common Test Scenarios
- Navigation menus and dropdowns
- Modal dialogs and overlays
- Form validation and submission
- Interactive carousels and sliders
- Accordion panels and tabs
- Shopping cart and checkout
Related Criteria
2.1.2 No Keyboard Trap
Users must be able to navigate away from elements
2.4.3 Focus Order
Focus order must be logical