Accessibility
Keyboard access: can you get through your website without a mouse?
What the guidelines require for keyboard use, where websites typically fail and how to check your own in ten minutes.
11 min read
By Timo Wessels Published
There is a test that takes ten minutes, needs no tool and finds more real problems than most automated checks: put the mouse aside and use your website with the keyboard alone. The Web Content Accessibility Guidelines (WCAG) require at the lowest level, A, that all functionality can be operated with the keyboard and that no element traps you. On top of that come a visible focus and a sensible order. The usual culprits are the menu, the cookie banner and windows that open and will not close again.
Who depends on the keyboard
In its explanation of success criterion 2.1.1 "Keyboard", the W3C names three groups:
- Blind people, who cannot use a mouse pointer because it relies on eye-hand coordination. Their screen reader is driven by the keyboard.
- People with low vision, who find it hard to follow the pointer on screen.
- People with hand tremors, for whom a mouse is a struggle.
Add everyone who uses a keyboard substitute: speech input, on-screen keyboards, sip-and-puff devices and scanning software. These systems send keystrokes to the page. Whatever does not work with the keyboard does not work with them either.
The requirement itself is short. Criterion 2.1.1, level A: all functionality must be operable through a keyboard interface without requiring specific timings for individual keystrokes. The only exception is input that depends on the path of the movement itself, such as freehand drawing. Missing this level is not a matter of polish.
How to check
Open your home page in a private browser window. That way you see the cookie banner as new visitors see it, not already dismissed. Then use only these keys:
| Key | What it does |
|---|---|
| Tab | moves to the next interactive element |
| Shift + Tab | moves back |
| Enter | activates links and buttons |
| Space | activates buttons and checkboxes, otherwise scrolls the page |
| Arrow keys | move within select fields, radio button groups and well-built menus |
| Esc | closes dialogs |
Look at five things as you go:
- Reach. Can you get to every link, every button, every form field and every menu item?
- Order. Does the path the focus takes make sense?
- Visible focus. Can you see where you are at every moment?
- Getting out again. Can you leave every element you reached?
- Full function. Does everything work, or are there things that only react when the mouse moves over them?
The visible focus
Criterion 2.4.7 "Focus Visible", level AA: any keyboard-operable interface has a mode of operation in which the keyboard focus indicator is visible. The focus ring is to a keyboard user what the pointer is to a mouse user. Without it you press Enter and do not know what is about to happen.
2.4.7 itself names no contrast value. That comes from criterion 1.4.11 on non-text contrast: the focus indicator needs 3:1 against the colours adjacent to it. If it sits outside the element, the background the element stands on counts. If it sits inside, the colours within the element count.
The most common mistake in this area is a single line of CSS. The W3C lists it as its own failure, F78:
:focus {
outline: none;
}
It turns up in many themes and custom stylesheets because the browser's default ring is considered ugly. Removing it without a replacement makes the website unusable for some visitors. The right way is to replace it:
:focus-visible {
outline: 3px solid var(--fokusfarbe);
outline-offset: 2px;
}
:focus-visible is the practical difference from :focus. The browser decides when a focus ring is needed: when tabbing, yes; when a button is clicked with the mouse, no. That ring on click was usually the reason it got removed in the first place.
Focus not obscured
Criterion 2.4.11 "Focus Not Obscured (Minimum)", level AA, arrived with WCAG 2.2 in October 2023: an element that receives focus must not be entirely hidden by other content on the page. Partly hidden still passes, although the W3C advises avoiding it where possible. The classic case is a header that sticks to the top: you tab on, the page scrolls along, and the focused element ends up right underneath. The same happens with cookie banners at the bottom edge, chat windows and non-modal dialogs. One fix the W3C names itself is the CSS property scroll-padding, set to the height of the fixed header.
The order
Criterion 2.4.3 "Focus Order", level A: where the order affects meaning or operation, focus must move in an order that preserves both. That does not mean the order has to match the screen exactly. The W3C gives an example of its own in which the navigation comes after the content in the source and is shown on the left with CSS, and it passes.
The natural order comes from the HTML source. Problems arise when source and display drift so far apart that the meaning is lost: grid layouts re-sorted with CSS, or blocks arranged differently on mobile than on desktop. This hits people using a screen magnifier hardest. The W3C writes that at high magnification they see only a small part of the page and easily read a field in the wrong context if focus jumps illogically.
tabindex is the most misused attribute in this field. MDN describes its three ranges like this:
tabindex="0"makes an element focusable. It takes its place in the order according to the source.tabindex="-1"takes an element out of the tab order. Focus can still be set there with JavaScript, which you need for dialogs, for example.- Positive values such as
tabindex="1"come before all elements with0or no value, wherever they are on the page.
MDN explicitly recommends using only 0 and -1. Positive values only work as long as they are maintained without gaps. As soon as someone adds content, the order breaks and nobody notices. The fix is not to repair the order with tabindex but to put the source in the right order.
Keyboard traps
Criterion 2.1.2 "No Keyboard Trap", level A: if you can get into an element with the keyboard, you must be able to get out with the keyboard. If that takes more than Tab, the arrow keys or the usual ways, the page has to say how.
A trap is the most serious failure in this area, because it does not make the website harder to use, it ends the visit. Anyone stuck can only reload. Typical places:
- Cookie banners. The banner appears but focus stays in the content behind it, and you never reach its buttons. Or the other way round: you get in and afterwards nowhere else.
- Modal windows. The dialog opens, focus stays in the background.
- Embedded content. Video players, maps, booking systems in a frame that capture the keyboard.
- Multi-level menus. The sub-items only open when the mouse moves over them. For keyboard users, half the website does not exist. This happens when a drop-down menu reacts only to
:hoverand not also to:focus-withinor a button.
How a dialog should work is described in the WAI pattern for modal dialogs: when it opens, focus moves into the dialog. Tab and Shift + Tab stay inside and wrap from the last element to the first. Esc closes it. Afterwards focus returns to the element that opened it. Keeping focus inside an open dialog is not a trap, as long as Esc or a close button leads out again.
Content that appears on hover or focus
Criterion 1.4.13, level AA, covers everything that is shown in addition: explanation boxes, drop-down menus, preview windows. Three conditions:
- Dismissible. The content can be closed without moving the mouse or the focus, usually with Esc.
- Hoverable. If it appears on mouse hover, you must be able to move the pointer onto it without it disappearing.
- Persistent. It stays visible until the trigger is removed, the user dismisses it or the information is no longer valid.
Excepted is what the browser presents itself, such as the tooltip from the title attribute.
A technical note on this: the onclick event of a link or button also responds to the keyboard, because it is bound to the element's default action. On a div that does not hold. Attaching a function only to onmouseover or onmousedown shuts keyboard users out, and the W3C lists exactly that as failure F54. onmouseover goes with onfocus, onmouseout with onblur.
Nothing may happen unexpectedly
Two level A criteria belong together:
3.2.1 "On Focus". Focusing an element must not by itself cause a change of context. The W3C gives three examples: a form is submitted, a new window opens, focus jumps somewhere else.
3.2.2 "On Input". Changing a setting must not cause a change of context unless the user was told beforehand. The classic is a select field that loads a new page as soon as it changes. For mouse users that is convenient. Anyone moving through the options with the arrow keys, on the other hand, triggers the change at the very first option. The fix is a button next to the select field that carries out the choice only on request.
What the law requires
Since 28 June 2025, Germany's Accessibility Strengthening Act (Barrierefreiheitsstärkungsgesetz, BFSG) applies to services for consumers, including e-commerce, such as online shops and bookings. Micro-enterprises with fewer than ten employees and an annual turnover or balance sheet total of at most 2 million euros are partly exempt. The benchmark is the European standard EN 301 549. According to the federal government, it adopts WCAG 2.1 and makes its levels A and AA mandatory. All criteria in this article except 2.4.11 belong to that core. 2.4.11 was added with WCAG 2.2 and is current practice. Whether your business falls under the law is a question for legal advice, not for a technical check.
What to do
- Search for
outline: noneandoutline: 0in your stylesheets. If there is no visible replacement, that is the first finding and usually the quickest to fix. - Set a focus style that fits the design. A clear outline in a colour from your palette, with a little distance from the element and 3:1 against the background. If the ring looks good, nobody removes it later.
- Fix the menu first. A drop-down menu that reacts only to
:hoverlocks keyboard users out of large parts of the website. - Take on the cookie banner. It is the first thing every visitor sees, and it usually comes from a third party. Check it with the keyboard in a private window before you check anything else.
- Remove positive
tabindexvalues and put the source in the right order instead. - Give fixed headers and footers
scroll-padding, so focus does not disappear beneath them. - Check again after every change. A new plugin or script can quietly break keyboard use. Ten minutes of tabbing belong in every maintenance round.
A tool that helps: Microsoft's browser extension Accessibility Insights for Web has a "Tab stops" test that shows each element's position as a number as you tab through. That makes jumps visible that are easy to miss when simply tabbing.
Sources
- W3C, Understanding WCAG 2.2 — 2.1.1 Keyboard: wording, level A, the groups affected, keyboard substitutes: w3.org
- W3C, Understanding WCAG 2.2 — 2.1.2 No Keyboard Trap, with the modal dialog as an acceptable case: w3.org
- W3C, Understanding WCAG 2.2 — 2.4.3 Focus Order, example with a differing source order, screen magnifiers: w3.org
- W3C, Understanding WCAG 2.2 — 2.4.7 Focus Visible, reference to 1.4.11: w3.org
- W3C, Understanding WCAG 2.2 — 1.4.11 Non-text Contrast, 3:1 for focus indicators against adjacent colours: w3.org
- W3C, Failure F78 —
outline: nonewithout a replacement: w3.org - W3C, Understanding WCAG 2.2 — 2.4.11 Focus Not Obscured, entirely versus partly hidden,
scroll-padding: w3.org - W3C, What's New in WCAG 2.2 — new criteria, published 5 October 2023: w3.org
- W3C, Understanding WCAG 2.2 — 1.4.13 Content on Hover or Focus, three conditions and the exception: w3.org
- W3C, Understanding WCAG 2.2 — 3.2.1 On Focus: w3.org
- W3C, Understanding WCAG 2.2 — 3.2.2 On Input: w3.org
- W3C, Technique SCR35 —
onclickon links and buttons is device-independent: w3.org - W3C, Failure F54 — functions only through mouse events: w3.org
- W3C, Technique SCR2 — mouse and keyboard events in pairs: w3.org
- W3C WAI, ARIA Authoring Practices — modal dialog pattern: w3.org
- MDN,
tabindex— the three ranges and the advice to use only 0 and -1: developer.mozilla.org - MDN,
:focus-visible— the difference from:focus: developer.mozilla.org - Federal accessibility portal (Portal Barrierefreiheit des Bundes) — Accessibility Strengthening Act, in force from 28.06.2025, micro-enterprises: barrierefreiheit-dienstekonsolidierung.bund.de
- Federal accessibility portal — WCAG 2.1 and EN 301 549, levels A and AA: barrierefreiheit-dienstekonsolidierung.bund.de
- Microsoft, Accessibility Insights for Web — FastPass with the "Tab stops" test: accessibilityinsights.io