Manual checks: the keyboard-only audit
Put the mouse down. In fifteen minutes you can find issues no scanner will ever flag.
The cheapest, highest-yield manual audit is also the simplest one: don't touch the mouse. Run through your app using only the keyboard, and write down every place it breaks down. You will find issues that no automated scan can detect, in less time than it takes to make coffee.
This isn't a stand-in for testing with real keyboard users — that matters too. It's the first pass: the one you do every release, against your own work, before anyone else sees it.
Setting up
You need almost nothing. A browser, your app, and these keys:
| Key | What it does |
|---|---|
| Tab | Move focus to the next interactive element |
| Shift + Tab | Move focus backwards |
| Enter | Activate links and buttons |
| Space | Activate buttons, toggle checkboxes, scroll |
| Arrow keys | Navigate within widgets (radios, menus, tabs, listboxes) |
| Escape | Close dialogs, popovers, and menus |
One small browser tweak before you start. Safari on macOS doesn't tab to links by default — turn that on under Settings → Advanced → "Press Tab to highlight each item on a webpage", or with defaults write com.apple.Safari WebKitTabToLinksPreferenceKey -bool true in the terminal. Without it your audit on Safari will be misleading.
Pin a sticky note that says "do not touch the mouse" to your monitor. Sounds silly. Works.
The walkthrough
A repeatable structure beats wandering. Use these five steps for any page.
1. Land on the page. Reload it. Where does focus start? It should be somewhere reasonable — the top of the document, a "skip to main" link, or the page heading. If your first Tab lands on the third item in a footer ad, that's a finding.
2. Tab from the top to the bottom. Don't skip. Watch for two things: that focus is always visible, and that the order matches the visual reading order. If focus disappears, even for one tab stop, write it down — that's a serious bug.
3. Try every interactive element you tab onto. Enter on links and buttons; Space on buttons and form controls. Anything you can click with a mouse, you should be able to operate from the keyboard. A "button" you cannot activate with Enter or Space is almost always a <div> someone forgot to make a real button.
4. Open every overlay, dialog, dropdown, and menu. Once it's open, try to:
- Tab without escaping it (focus should be trapped inside).
- Press
Escapeto close it. - Confirm focus returns to the element that opened it.
5. Submit a form. Submit it empty and submit it valid. Errors should move focus to the first invalid field, or at least announce themselves to assistive tech. Success should land somewhere sensible — usually a confirmation message that announces itself.
Fifteen minutes per significant page. If a page takes longer because it has six dropdowns and a wizard, that's a sign of where to spend your follow-up time.
What to watch for
A short list of the things that come up the most:
- Invisible focus. A
:focus { outline: none }rule somewhere in the CSS, with nothing replacing it. Sighted keyboard users now have no idea where they are. - Trap escape. Open a modal, hit
Tabenough times, and you're tabbing into the page behind it. Bad — focus should cycle within the modal. - No escape. Same modal, no
Escapehandler. Now your only way out is to find and click a close button you cannot see. - Mouse-only widgets. Hover-only menus, drag-only sorters, click-only-on-an-icon-with-no-keyboard-equivalent.
- Skipped focus. Custom widgets that aren't tabbable at all because they're built on
<div>and<span>. - Out-of-order focus. A sidebar that's visually on the right but tabs first because it's earlier in the DOM. (Or worse, a
tabindexgreater than zero that jumps focus around.) - Disappearing focus on route change. SPAs that swap content but leave focus on a button that no longer exists. The user is now focused on the body element with no anchor.
Avoid tabindex values greater than zero. They override DOM order and almost always create the
out-of-order bugs you're trying to find. The only sensible values are 0 (in tab order) and
-1 (focusable programmatically, not in tab order).
Logging findings
A bug report a teammate can act on has four fields:
- Page: /checkout/review
- What I did: Tabbed forward from the page heading.
- What happened: Focus jumped from the heading to the footer, skipping the order summary entirely.
- Expected: Focus should reach the "Place order" button before the footer.
That's it. No screenshots required for keyboard issues, though a short screen recording with focus indicators visible is gold for the developer who fixes it. Tools like the Accessibility Insights extension include a "tab stops" feature that overlays the tab path on the page — perfect for capturing.
A scoring shortcut for triage: Critical if focus is invisible or you can't operate the control at all; High if it works but the order is wrong; Medium for paper cuts like a slightly confusing focus indicator. We'll come back to triage in lesson 7.
Check yourself
tabindex="3" to a button so it gets focused early. What should you do?