How to Test Keyboard Accessibility by Hand, Step by Step
Put the mouse away, press Tab, and work the page in order: the checks a scan cannot make for you, and the WCAG 2.2 criterion behind each one.
A keyboard pass is the cheapest manual test an agency can run. No software, no screen reader training, no client sign-off, and it finds the failures that make a site unusable rather than imperfect: a hover-only menu, a modal you cannot leave, a focus ring somebody deleted in a stylesheet.
This is the procedure, in order, with the WCAG 2.2 criterion behind each step so the finding writes itself into the report. For the theory, our keyboard navigation guide covers how focus, tab order and skip links work. This is the test.
Set up before you press Tab
On macOS, turn on Full Keyboard Access first. Without it Tab skips buttons, checkboxes and radio buttons in some browsers, and you will file a bug that is not there. Apple's path: Apple menu > System Settings > Accessibility, then "Go to Motor, click Keyboard, then turn Full Keyboard Access on or off" (Apple, Use Full Keyboard Access). In Safari, also switch on "Press Tab to highlight each item on a webpage" under Safari > Settings > Advanced (Apple, Change Advanced settings in Safari). Windows and Linux need no setup.
Then move the mouse out of reach. Not metaphorically. Every tester who keeps a hand on the trackpad rescues themselves from a trap without noticing it.
One helper: paste this into the console, so you can always answer "what has focus right now" when the page shows nothing.
// Logs the element that has focus every time it changes
document.addEventListener('focusin', () => console.log(document.activeElement));
The keys you will use
Tab and Shift + Tab move between components. Enter follows a link or activates a button, Space activates a button or toggles a checkbox, the arrows move inside a component such as a tab list, and Escape closes a dialog or menu. W3C's own quick check is the same short list, and asks you to confirm that "the focus is clearly visible as you tab through" (W3C WAI, Easy Checks).
The pass, step by step
1. Press Tab once, before anything else
The first Tab should reveal a skip link. If nothing appears, note it. A mechanism to bypass repeated blocks of content is 2.4.1 Bypass Blocks, Level A: "A mechanism is available to bypass blocks of content that are repeated on multiple web pages."
Then press Enter and Tab again. A skip link that moves the scroll position but not focus is the common half-broken version, and the next Tab gives it away by landing back in the nav.
<!-- Broken: nothing receives focus, so the next Tab returns to the nav -->
<a href="#main">Skip to content</a>
...
<div id="main">
<!-- Fixed: the target is a real landmark and can take focus -->
<a href="#main" class="skip-link">Skip to content</a>
...
<main id="main" tabindex="-1">
2. Tab through the header and watch the focus ring
One thing matters here: can you see where you are, at every stop. 2.4.7 Focus Visible, Level AA requires that "any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible".
The usual cause is one line in a stylesheet.
/* Broken: removes the indicator and replaces it with nothing */
*:focus { outline: none; }
/* Fixed: a visible ring for keyboard users, no ring on mouse clicks */
:focus-visible {
outline: 3px solid currentColor;
outline-offset: 2px;
}
Watch for the subtler version: a ring that vanishes against a dark hero, a white button or a photograph. WCAG 2.2 does set a measurable bar for indicator size and contrast in 2.4.13 Focus Appearance, but that one is Level AAA, so in an AA audit raise it against 2.4.7 rather than as an AA failure.
3. Watch the order, not just the stops
2.4.3 Focus Order, Level A: focusable components must "receive focus in an order that preserves meaning and operability". Focus follows the DOM, so this breaks wherever CSS reorders content visually. Flex and grid ordering, absolutely positioned cards and "sidebar first in the markup, last on screen" layouts are the repeat offenders.
Tab slowly and ask whether each jump would make sense to someone looking at the page. Focus that leaps from a card grid to the footer and back is a finding even when every element is reachable.
4. Scroll down and check nothing covers the focused element
This is the step most testers skip, and the newest AA requirement in this area. 2.4.11 Focus Not Obscured (Minimum), Level AA: "When a user interface component receives keyboard focus, the component is not entirely hidden due to author-created content."
W3C names the suspects directly: "Typical types of content that can overlap focused items are sticky footers, sticky headers, and non-modal dialogs", and "a notification implemented as sticky content, such as a cookie banner, will fail this success criterion if it entirely obscures a component receiving focus" (Understanding SC 2.4.11).
So load the page fresh with the cookie banner up, Tab past the fold, and watch the sticky header. When a focused link slides under it, you have it. The fix is usually scroll-padding-top, set to the height of the sticky bar.
5. Reach and operate every control
2.1.1 Keyboard, Level A requires that "all functionality of the content is operable through a keyboard interface". Try to do things, not just arrive at them. Failures cluster in four places:
- Hover-only menus. Tab reaches the top item, but the submenu never appears.
- Divs and spans with a click handler. Invisible to Tab, because they are not interactive elements.
- Drag-only interactions. Sliders, sortable lists and map controls that answer a drag and nothing else.
- Custom selects and comboboxes. Reachable, but Enter, Space and the arrows do nothing useful. Our guide on accessible custom dropdowns and comboboxes has the pattern that works.
<!-- Broken: not focusable, not announced, Enter and Space do nothing -->
<div class="btn" onclick="save()">Save</div>
<!-- Fixed: focusable, announced as a button, activates on Enter and Space -->
<button type="button" class="btn" onclick="save()">Save</button>
6. Inside a component, Tab should stop and the arrows should take over
A tab list, menubar, radio group or grid should be one stop in the tab sequence, not one per item. The W3C ARIA Authoring Practices Guide puts it plainly: "the tab sequence should include only one focusable element of a composite UI component", while "the arrow keys, move focus inside of components that include multiple focusable elements" (APG, Developing a Keyboard Interface).
So at a set of tabs, press Tab once, then try the arrows. Twelve Tab presses to cross twelve tabs is a finding, and so are arrows that do nothing. Our post on accessible accordions and tabs covers the patterns.
7. Open the modal, then try to leave
Modals produce two findings, so check both. While it is open, Tab in a full circle: focus should stay inside the dialog. Then close it with Escape: focus must return to the control that opened it, not the top of the document.
Then keep tabbing. If focus can enter a component but not leave it by keyboard, that is 2.1.2 No Keyboard Trap, Level A: "If keyboard focus can be moved to a component of the page using a keyboard interface, then focus can be moved away from that component using only a keyboard interface." Third-party embeds, video players and rich text editors are the usual sources. Accessible modals has the focus management pattern.
8. Fill in a form and submit it wrong on purpose
Tab into each field and check that nothing happens on arrival. 3.2.1 On Focus, Level A: "When any user interface component receives focus, it does not initiate a change of context." A select that navigates on focus, a field that opens a help dialog and steals focus, a form that submits itself: all failures.
Then submit with an empty required field and Tab onward. Can you reach the error message? Does focus go anywhere sensible? An error that is only a red border is a real bug in a checkout, and the one clients care about once you show them.
9. Shift + Tab all the way back up
Run the page backwards. Traps and one-way focus scripts often only show up in reverse: the code that moves focus forward was never written to move it back.
What each step maps to in your report
| Step | Success criterion | Level |
|---|---|---|
| Skip link | 2.4.1 Bypass Blocks | A |
| Focus ring visible at every stop | 2.4.7 Focus Visible | AA |
| Order matches the page | 2.4.3 Focus Order | A |
| Sticky header or banner covers focus | 2.4.11 Focus Not Obscured (Minimum) | AA |
| Everything reachable and operable | 2.1.1 Keyboard | A |
| Cannot get out of a widget | 2.1.2 No Keyboard Trap | A |
| Something happens on focus | 3.2.1 On Focus | A |
All criterion numbers, titles, levels and quoted text above come from WCAG 2.2.
Where the automated scan still earns its place
A scanner beats a person at what is countable on every page: missing labels, contrast ratios, an outline: none rule, elements with no accessible name. It cannot tell you whether the focus order made sense, whether the sticky header covered the link you were on, or whether Escape put focus back where it belonged. Those are judgement calls, which is why this pass exists.
Our keyboard and focus checker flags the machine-detectable half on every page you add, and a free accessibility audit gives you a starting point before you open a client page by hand. What neither can do, and what no automated tool can do, is confirm that a site conforms to WCAG: automated checks find many real problems, but conformance is a human judgement about every criterion on every page. Say that to clients plainly. We covered the gap in six accessibility checks most scanners miss.
Your checklist
Paste it into the audit template. Roughly twenty minutes once it is familiar.
- Full Keyboard Access on (macOS), Tab highlighting on (Safari), mouse away.
- First Tab reveals a skip link, and Enter on it moves focus.
- Focus is visible at every stop, on every background.
- Focus order matches the visual order.
- With the cookie banner and sticky header up, no focused element is fully covered.
- Every menu, control and custom widget can be operated, not just reached.
- Composite widgets are one tab stop, with arrow keys inside.
- Modals hold focus while open and return it to the trigger on Escape.
- No field changes context on focus, and form errors are reachable.
- The whole page again with Shift + Tab.
- Every finding written down with its criterion number, level and element.
Write each finding as what you did and what happened: "pressed Escape on the booking dialog, focus went to the top of the page, WCAG 2.4.3 Focus Order (A)". A developer reproduces that in ten seconds. "Keyboard accessibility needs improvement" gets deferred to next quarter.