Level A · WCAG 2.0
2.1.1 Keyboard
Everything that works with a mouse works with a keyboard.
Partly automated Some failures are detectable, others need judgement.
How it fails in practice
A carousel whose arrows are divs with click handlers. A custom select that opens on click and cannot be opened with Enter. A drag-to-reorder list with no keyboard path at all.
How to fix it
Use real button and a elements. Where a custom widget is unavoidable, implement the keyboard interaction its ARIA pattern specifies — not just Tab.
At a glance
- Level
- Level A — the minimum. Failing one of these usually makes something impossible rather than merely hard.
- Principle
- Operable
- Guideline
- 2.1 Keyboard Accessible
- Added in
- WCAG 2.0
- EN 301 549
- 9.2.1.1
- Automated check
- Partly automated
How to test it by hand
- Put the mouse away. Click into the address bar, then press Tab through the whole page.
- Check that you can reach every link, button, field and menu, and operate each one — Enter for links and buttons, Space for checkboxes and buttons, the arrow keys inside menus, tabs and radio groups.
- Walk the journey that earns the money: search, filter, choose a size, add to basket, check out, pay. One step that needs a mouse fails the whole journey.
- Watch the custom widgets closely — sliders, date pickers, carousels, cookie banners, chat windows. That is where the failures are.
In code
<div class="add-to-basket" onclick="addToBasket()">
Add to basket
</div>
<button type="button" class="add-to-basket" onclick="addToBasket()">
Add to basket
</button>
Partly automated
How far an automated check gets
A tool finds some failures here and cannot see the rest. A clean automated result means the checks that exist found nothing — not that the criterion is met. This is the gap that makes a green scan look like an accessible site, and it is where the keyboard agent, the agents still in development and a human reviewer do the remaining work.
Our keyboard agent walks the journeys you give it and records every keystroke, so a failure comes with the trail that produced it. On a crawl from an account it also walks one page of each template and presses what it reaches, which finds controls that react to a click and to no key. It still does not try every widget on the site.
Rules that check this criterion
frame-focusable-contentFrames with focusable content must not have tabindex=-1scrollable-region-focusableScrollable region not keyboard accessibleserver-side-image-mapServer-side image maps must not be usedkeyboard:unreachableElement not reachable by keyboard Keyboard agent
The rule ids are axe-core’s (version 4.14.0), the open-source engine our scan runs, and our keyboard agent’s — the names a report or a CI log will show. An underlined id has a page of its own here.
Where it matters most
The guides that list it among the criteria to check first.
- BFSG for online shops
- BFSG for banking and financial services
- BFSG for ticketing and passenger transport
- BFSG for e-books and reading apps
- BFSG for telecommunications services
- Shopware accessibility and the BFSG
- Shopify accessibility and the BFSG
- TYPO3 accessibility and the BFSG
- WordPress accessibility and the BFSG
Related criteria
Other criteria under the same guideline.
Further reading
-
Keyboard agent
Keyboard accessibility testing with real keys: the agent tabs through your pages, finds keyboard traps and invisible focus, and records every step.
-
Keyboard accessibility
Every function of a website can be operated with a keyboard alone, without a mouse (WCAG 2.1.1, Level A).
-
keyboard:unreachable
A clickable div or a role="button" no Tab reaches fails WCAG 2.1.1. Why it happens, how to fix it with real buttons and links, with code example.
-
scrollable-region-focusable
The axe rule scrollable-region-focusable flags a scrolling box that keyboard users cannot reach or scroll. How to fix it with tabindex, with code example.
Find out which criteria your site fails
We scan up to 100 pages against WCAG 2.2 AA, send the keyboard agent through the page you name and email you the report — free, once, no strings.