To test a site by keyboard, put the mouse away and use Tab, Shift+Tab, Enter, Space and the arrow keys to reach and operate everything, watching for a visible focus ring and a sensible order. Then turn on a screen reader, NVDA on Windows or VoiceOver on Mac, and check that headings, links, buttons and form fields are announced clearly.
| Criterion | Level | What you check |
|---|---|---|
| 2.1.1 Keyboard | A | Everything works without a mouse |
| 2.1.2 No Keyboard Trap | A | Focus can always move away again |
| 2.4.1 Bypass Blocks | A | A way to skip repeated navigation |
| 2.4.3 Focus Order | A | Tab order follows the meaning of the page |
| 2.4.7 Focus Visible | AA | You can always see where focus is |
| 2.4.11 Focus Not Obscured (Minimum) | AA | Sticky bars do not hide the focused item |
| 4.1.2 Name, Role, Value | A | Controls announce what they are and their state |
Updated
Automated checkers catch missing alt text and low contrast, but they cannot tell whether a menu can be opened with Enter or whether a screen reader user understands a form. This page walks through the manual pass in order, with a practice area that shows exactly which element has focus and a checklist that keeps your place.
Tick each step as you test. Your ticks stay on this page only.
Tab through these controls. The tracker names the element that has focus right now.
| Key | What it should do |
|---|---|
| Tab / Shift+Tab | Move to the next or previous focusable element |
| Enter | Follow a link or press a button |
| Space | Press a button, tick a checkbox, scroll the page when nothing is focused |
| Arrow keys | Move within radio groups, selects, menus and tab lists |
| Escape | Close a dialog, menu or popup |
The NVDA key is Insert by default; the user guide also allows Caps Lock. Single letter keys work in browse mode.
| Action | Keys |
|---|---|
| Start NVDA | Control+Alt+N |
| Stop speech | Control |
| Read from here (say all) | NVDA+Down Arrow |
| Switch browse and focus mode | NVDA+Space |
| Elements list (links, headings, landmarks) | NVDA+F7 |
| Next heading / landmark / link | H / D / K |
| Next form field / button | F / B |
| Next table / list | T / L |
| Quit NVDA | NVDA+Q |
VO means the VoiceOver modifier: Control and Option held together, or Caps Lock on its own.
| Action | Keys |
|---|---|
| Turn VoiceOver on or off | Command+F5 |
| Open the rotor | VO+U |
| Switch rotor list (headings, links and more) | Left or Right Arrow inside the rotor |
| Move through the chosen list | Up or Down Arrow inside the rotor |
Click inside the result, then press Tab. The link slides into view only when focused, and its target is the main element.
<style>
.skip { position: absolute; left: 8px; top: -60px; padding: 8px 14px; background: #111; color: #fff; border-radius: 8px; }
.skip:focus { top: 8px; }
nav a { margin-right: 10px }
</style>
<a class="skip" href="#main">Skip to content</a>
<nav aria-label="Main"><a href="#">Home</a><a href="#">Services</a><a href="#">Contact</a></nav>
<main id="main" tabindex="-1"><h1>Page title</h1><p>Main content starts here.</p></main>Tab to the buttons inside the result. The offset ring stays clear of the button edge, and mouse clicks usually leave it hidden.
<style>
button { padding: 8px 14px; margin: 6px; border-radius: 8px; border: 1px solid #94a3b8; background: #fff; }
button:focus-visible { outline: 3px solid #1d4ed8; outline-offset: 3px; }
</style>
<button>First</button><button>Second</button><button>Third</button>scroll-padding-top reserves space at the top when the browser scrolls a focused element or an anchor into view.
html { scroll-padding-top: 5rem; } /* height of the sticky header plus a little room */
header { position: sticky; top: 0; }
Screen readers read web pages in a virtual buffer where single letters jump around: H for the next heading, K for the next link in NVDA. When you land in a text field the reader switches to focus mode so letters type instead. NVDA+Space toggles between the two by hand.
This is why a custom widget that only reacts to arrow keys can seem broken. In browse mode the reader may consume those keys before your script hears them, so use native elements or follow the ARIA Authoring Practices patterns.
Each control should be announced as a name, a role and, where relevant, a state: Search, edit text; Menu, button, collapsed; Subscribe, checkbox, not checked. If any of the three is missing, fix the markup before adding ARIA.
Headings should form an outline you could read as a table of contents. Pull up the headings list in NVDA's elements list or the VoiceOver rotor and see whether it makes sense alone.
Write each issue as the page, the steps, what you expected and what happened, plus the criterion it fails. That format lets a developer reproduce it without guessing.
Retest after fixes with the same steps. Focus problems in particular tend to reappear when a header or modal is restyled.
Use what your visitors use where possible. NVDA is free for Windows from NV Access, and VoiceOver is built into every Mac and iPhone. If most of your traffic comes from phones, add a pass with VoiceOver on iPhone or TalkBack on Android.
NVDA starts with Control+Alt+N once installed, and Insert+Q quits it. On a Mac, Command+F5 turns VoiceOver on and off. Pressing Control on its own silences NVDA mid-sentence.
It is the first link on the page, usually hidden until it receives focus, that jumps straight to the main content. Keyboard users then avoid tabbing through the whole navigation on every page. WCAG lists it as one sufficient technique for 2.4.1 Bypass Blocks, alongside landmarks and headings.
:focus-visible lets the browser decide when a focus ring is useful, so keyboard users see it while mouse clicks on buttons usually do not draw one. It has been widely supported since March 2022 according to MDN. Style :focus-visible and keep a visible ring for every interactive element.
A spot where focus goes in and cannot get out with the keyboard, such as an embedded player or a custom dialog that swallows Tab. Modal dialogs should keep focus inside while open, but Escape or a close button must always let the visitor leave.
Related: Website accessibility checklist, aria-label examples, HTML accessibility checker, Colour contrast checker, JavaScript event listeners.
Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.
We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.