Keyboard testing as a habit
Unplug your mouse for an hour. The bug list that emerges is the work.
Everything in this course is theory until you actually press Tab through your own app. The fastest, cheapest accessibility audit you can do is to put your mouse in a drawer for an hour and try to use what you've shipped. You'll find more bugs than any automated tool will, in less time than reading any spec.
This lesson is about making that exercise a habit, not a one-off.
The one-hour session
The exercise is simple:
- Pick a real flow in your app — sign up, post something, check out, change a setting.
- Move your mouse out of reach. Hide it under a book if you have to.
- Walk through the flow using only the keyboard.
- Write down every place you got stuck, confused, or had to cheat by reaching for the mouse.
That list is your sprint. Don't tackle it now — just collect it. Most teams who do this for the first time generate 20+ items in an hour from one flow.
The first session always feels brutal. That's not because keyboard navigation is hard — it's because your app probably has a lot of bugs you haven't seen. Each one is a real user's daily frustration.
What to look for
A short, opinionated checklist, drawn from the previous six lessons:
Reaching things
- Can you Tab to every interactive element? (Or did you just hit a
<div>someone slapped a click handler on?) - Does Tab order match the visual order, top-left to bottom-right?
- Is there a skip link? Does it work?
- After a route change, does focus end up on the new page's heading or main? Or are you still in the nav?
Seeing focus
- Is there a visible ring on every focusable element?
- Is the ring distinct from the hover state?
- Does the ring still appear in Forced Colors Mode? (Toggle "Emulate forced-colors: active" in DevTools.)
- Does the ring have at least 3:1 contrast with its background?
Modals and overlays
- When a modal opens, does focus move into it?
- Can you Tab out of the modal? (You shouldn't be able to.)
- Does Esc close it?
- When it closes, does focus go back to the trigger?
Custom widgets
- Do menus, tabs, comboboxes, and trees use the keys you'd expect from APG?
- Can you operate them without ever touching the mouse?
- Do they communicate state — open/closed, selected, expanded — via ARIA?
Forms
- Does Enter submit the form when focus is in a single-line input?
- Do error messages get announced? Does focus move to the first invalid field?
If three or more of these are wrong on a page, your priority isn't fancy ARIA — it's the basics in this list.
Tools that help (and don't)
A few things to clear up:
Automated tools (axe, Lighthouse, Pa11y) catch maybe 30–40% of accessibility issues. They're great at finding missing alt text, low contrast, broken ARIA references. They're bad at finding "this menu doesn't respond to arrow keys" or "focus is stuck inside the closed modal." Run them, take their findings seriously, but don't treat a green score as proof of accessibility.
Browser DevTools are increasingly useful. Chrome and Edge can emulate Forced Colors Mode, color blindness, and more. Firefox has a great Accessibility Inspector that shows the accessibility tree as the OS sees it.
Screen readers are essential for testing screen-reader bugs, but they're a separate skill. For the keyboard exercise in this lesson, you don't need a screen reader — you need a keyboard. Don't let the perfect be the enemy of the started.
An accessibility overlay widget — the floating button that promises to "fix" your site by toggling fonts and colors — does not fix keyboard bugs. Don't ship one and consider it done. Several have actually been sued for making accessibility worse.
Making it a habit
A one-hour session every six months catches the worst bugs. The teams who actually ship accessible products go further:
- One hour, every sprint. Same flow each time? Different flow each time? Either works. Consistency matters more than scope.
- Add it to your definition of done. "Tab through the new component. Esc closes it. Focus returns to the trigger." Three lines on a checklist that catches 80% of regressions.
- Pair-test. Two people, one keyboard. The driver navigates; the navigator narrates what they expect to happen. The places those expectations diverge are the bugs.
- Watch a real keyboard user. A user research session with someone who relies on keyboard navigation will surface bugs your team would never find.
- Make automated checks part of CI. axe-core, jest-axe, Playwright with @axe-core/playwright. They miss things, but they catch regressions on the things they do check.
The goal is not to ship a perfectly accessible app. The goal is to never not be checking. Most accessibility debt accumulates because no one looked, not because anyone made hard choices.