Test Your Site with Only a Keyboard
03 Nov 2026Unplug your mouse and try to complete your own signup flow. Ten minutes, no tools, and it finds bugs that Lighthouse and axe both miss — because automated scanners check for the presence of ARIA attributes, not whether tabbing through the page actually makes sense.
The audit
flowchart TD
A["Load the page"] --> B["Press Tab repeatedly"]
B --> C{"Focus visible at every stop?"}
C -->|No| X1["Bug: missing focus style"]
C -->|Yes| D{"Order matches visual/logical order?"}
D -->|No| X2["Bug: DOM order or tabindex problem"]
D -->|Yes| E{"Every interactive element reachable?"}
E -->|No| X3["Bug: div/span used as button, no tabindex"]
E -->|Yes| F["Open a modal or menu"]
F --> G{"Focus moves into it?"}
G -->|No| X4["Bug: no focus management on open"]
G -->|Yes| H{"Escape closes it and returns focus?"}
H -->|No| X5["Bug: no escape handler / focus not restored"]
H -->|Yes| I{"Tab stays trapped inside while open?"}
I -->|No| X6["Bug: no focus trap, tabs to page behind modal"]
I -->|Yes| J["Pass"]
Walk your actual critical paths this way — signup, checkout, search — not just the homepage.
What to check at each stop
Tab moves forward, Shift+Tab moves back. At every stop, ask two questions: can I see where I am, and does this order make sense. A visible focus ring that jumps from the header straight to a footer link, skipping the entire main content area, means something in the middle has no interactive elements or a broken tab order.
Enter activates links and submit buttons. Space activates buttons and toggles checkboxes. If a clickable element does nothing on Enter or Space, it’s very likely a div or span with a click handler instead of a real button, a, or input. This is the single most common finding on this audit.
<!-- Not keyboard accessible by default -->
<div onclick="toggleMenu()">Menu</div>
<!-- Accessible for free -->
<button onclick="toggleMenu()">Menu</button>
A native button gets focusability, Enter/Space activation, and correct default styling with zero extra code. Reach for a real element before reaching for tabindex="0" plus a keydown handler to fake it.
The modal trap, specifically
This is where most sites fail. Open any modal, dropdown menu, or dialog with the keyboard and check three things: does focus move into it on open, does Tab stay contained inside it while it’s open (don’t let a user tab into a page element hidden behind the overlay), and does Escape close it and return focus to whatever opened it. Getting all three right by hand is fiddly — if you’re not using the native dialog element, which handles most of this for you, budget real time for it rather than assuming your custom modal component gets it right by accident.
<dialog id="confirm">
<p>Delete this item?</p>
<button autofocus>Cancel</button>
<button>Delete</button>
</dialog>
<script>
document.getElementById('confirm').showModal();
</script>
showModal() handles focus trapping and Escape-to-close natively. autofocus puts initial focus where you want it.
Where automated tools help anyway
Run axe or Lighthouse first — they’ll catch missing labels and contrast issues faster than you will by hand. But they cannot tell you whether the tab order is logical or whether your modal traps focus correctly. That’s a “sit down and press Tab” problem, every time. Ten minutes per critical flow, done manually, catches what the scanner can’t.