Some visitors never touch a mouse. They may have a motor impairment, use a switch device or speech software, rely on a screen reader, or simply prefer the keyboard. If a menu opens only on hover, a button is really a styled div, or the highlight showing where you are has been switched off in the CSS, those visitors are stuck. Keyboard accessibility means every link, button and form control can be reached, seen and used with the keyboard alone.
A short walk through your key pages with the Tab key turns up many problems without special software. This guide shows how to run it, what each failure means under the Web Content Accessibility Guidelines (WCAG) 2.2, and how to fix it with small changes to HTML and CSS.
It is for site owners, designers and developers. You will finish with a tested set of pages, a visible focus style and a working skip link. Nothing here makes a site "compliant" on its own, and this is not legal advice.
Short answer: To test keyboard accessibility, put the mouse aside and press Tab through each page. Check that you can reach and operate every control, that a visible indicator shows where focus is, that the order follows the layout, and that you can always leave a widget with the keyboard.
Before you begin
You need a desktop browser, the URLs of your five to ten most important pages (home, a content page, contact or checkout, search, login) and about an hour. Ignore the mouse. Work on a staging copy if you plan to change code. CSS changes to focus styles touch every page, so keep a copy of the stylesheet you edit.
If you have not run a broader review, start with Website Accessibility Audit: Fix the Most Common Problems or the quick questions in How do I check if my website is accessible?, and return here for the deeper keyboard checks.
What does keyboard accessibility require under WCAG?
These WCAG success criteria cover keyboard use, with their WCAG 2.2 levels:
| Criterion | Level | In plain words |
|---|---|---|
| 2.1.1 Keyboard | A | All functionality works from a keyboard interface, except where the function depends on the path of a pointer (freehand drawing, for example). |
| 2.1.2 No Keyboard Trap | A | If focus can move into something, it can move out again with the keyboard, and the user is told how if it takes more than Tab, arrow keys or another standard exit. |
| 2.4.1 Bypass Blocks | A | There is a way to skip blocks repeated on many pages, such as a skip link, headings or landmarks. |
| 2.4.3 Focus Order | A | Focusable items receive focus in an order that keeps meaning and operation. |
| 2.4.7 Focus Visible | AA | The keyboard focus indicator is visible in at least one mode of operation. |
| 2.4.11 Focus Not Obscured (Minimum) | AA | A focused component is not entirely hidden by content you created, such as a sticky banner. New in WCAG 2.2. |
WCAG 2.2 also has stricter AAA versions (2.4.12, where no part of the focused item may be hidden, and 2.4.13 Focus Appearance). Level AA is the usual target for a business site. For the full AA list, see WCAG 2.2 Checklist: Level AA Items for Small Business Websites.
Step-by-step instructions
Step 1: Walk each page with Tab and Shift+Tab
Load the page, click once on blank space near the top, then press Tab repeatedly and Shift+Tab to go back. Use Enter on links and buttons, Space on buttons and checkboxes, arrow keys in radio groups and menus, and Escape to close pop-ups. Note every control you cannot reach or operate, and every moment you lose track of where you are.
Count the stops before the main content begins. If the number is large, Step 4 solves it. Include cookie banners, chat widgets, pop-ups and mobile menu buttons.
What success looks like: Every link, button, field and menu item you can click, you can also reach with Tab and activate from the keyboard, and nothing that is not interactive takes a tab stop.
Step 2: Check that focus is always visible
While tabbing, watch for the focus indicator: a ring, underline, thick border or background change. If it vanishes on any control, you have found an SC 2.4.7 failure. The usual cause is a rule like outline: none or outline: 0 with no replacement. W3C lists styling that removes the indicator as a named failure (F78), and keeping the browser's default indicator counts as a sufficient technique.
For a custom style, use :focus-visible. MDN explains that it matches when the browser decides focus should be made evident: for keyboard use, in practice, while a mouse click on a button usually does not trigger it. That keeps a strong ring for keyboard users without an obtrusive one after a click:
/* One visible focus style for all interactive elements */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible {
outline: 3px solid #0b3d91;
outline-offset: 2px;
}
The indicator also has to be seen against whatever sits next to it. WCAG 1.4.11 asks for at least a 3:1 contrast ratio between a focus indicator you styled and the adjacent colors; the plain browser default is exempt from that ratio but must still be visible. On dark sections a dark ring disappears, so give those areas a light ring or use a two-color indicator. For measuring ratios, see Color Contrast and WCAG: Ratios, Checks and Fixes.
What success looks like: You can always say which element has focus, including on dark backgrounds and inside forms.
Step 3: Check that the tab order matches the layout
Focus should move in an order that keeps the meaning of the page, usually the same as reading order. Problems come from two places. The first is positive tabindex values such as tabindex="3": MDN advises using only 0 and -1, because positive values jump ahead of everything else and make navigation hard to predict. The second is CSS that reorders content visually (flex order, grid placement, absolute positioning) while the HTML stays in another sequence. MDN warns against that as well. The fix is to write the HTML in the order you want people to meet it.
Use tabindex="0" only to put a custom component in the natural order, and tabindex="-1" when a script needs to move focus to something, such as an error message, without making it a tab stop. Do not add tabindex="0" to paragraphs; every extra stop slows keyboard users.
What success looks like: Focus moves through the page in the order a sighted reader would scan it, with no unexpected jumps to the footer or back to the top.
Step 4: Add and test a skip link
Without one, keyboard users tab through your logo, navigation and search box on every page. A skip link is the first focusable element and jumps to the main content. W3C lists it among the sufficient techniques for SC 2.4.1, alongside headings and landmarks. web.dev notes that it can be always visible or hidden until it receives focus, and that its text should say what it does.
<body>
<a class="skip-link" href="#main">Skip to main content</a>
<header>...navigation...</header>
<main id="main" tabindex="-1">
<h1>Page title</h1>
</main>
</body>
.skip-link {
position: absolute;
left: 0.5rem;
top: -4rem;
background: #fff;
color: #0b3d91;
padding: 0.5rem 1rem;
}
.skip-link:focus { top: 0.5rem; }
Test it: press Tab once on a fresh page load, confirm the link appears, press Enter, then press Tab again. Focus should continue from inside the main content, not from the top. If it restarts at the header in your browser, the tabindex="-1" on the target (MDN describes -1 as focusable by script or click but not by Tab) is a common remedy.
What success looks like: One Tab press reveals the skip link, Enter takes you to the content, and the next Tab press lands on the first control in the main area.
Step 5: Check that sticky elements do not cover the focused item
WCAG 2.2 added 2.4.11 at Level AA. A sticky header, footer or cookie banner that completely covers a control when it receives focus fails. W3C's guidance says partial overlap passes at AA, and it names CSS scroll-padding as a technique: it makes the browser scroll the focused item clear of the sticky area.
html { scroll-padding-top: 5rem; } /* height of a sticky header */
html { scroll-padding-bottom: 4rem; } /* height of a sticky footer or banner */
Test by tabbing through the page with every sticky element showing, at narrow and full width. The same W3C page also lists making a banner modal, or closing a no-action notification when it loses focus.
What success looks like: At every stop, at least part of the focused control is visible, and ideally all of it.
Step 6: Hunt for keyboard traps and unreachable widgets
A keyboard trap means focus enters a component and cannot leave by keyboard. Embedded players, rich text editors and badly built pop-ups are the usual places. A modal dialog that keeps Tab inside it is not a failure if users can close it; W3C's example closes with Cancel, OK or Escape. Anything beyond standard keys must be explained to the user.
Then test components that imitate native controls. A div with a click handler cannot be focused or triggered with Enter or Space. MDN advises real button, a and input elements, which bring role, focus and keyboard behaviour with them; a div made focusable with tabindex leaves you to rebuild all of that.
<!-- Fails: not focusable, no keyboard activation, no role -->
<div class="btn" onclick="openMenu()">Menu</div>
<!-- Passes: native button with name, role and keyboard support -->
<button type="button" class="btn" aria-expanded="false" aria-controls="menu">Menu</button>
Menus that open only on mouse hover need an equivalent on focus or click. If a handler never fires, look for script errors first: Find and Fix JavaScript Console Errors on Page Load shows how. Also check that focusing a control never submits a form, opens a window or moves focus elsewhere (SC 3.2.1); W3C's failure examples include scripts that remove focus the moment it arrives (F55).
What success looks like: Every widget can be entered, operated and exited with the keyboard, any special exit key is shown on screen, and tabbing through a form changes nothing until the user acts.
Final verification checklist
- You tested keyboard accessibility by tabbing through each key page with no mouse, including the cookie banner, header, forms and footer.
- Every interactive element is reachable with the keyboard and operable with Enter or Space as expected.
- A focus indicator is visible on every control, on light and dark backgrounds.
- No positive
tabindexvalues remain, and the visual order matches the HTML order. - A skip link appears on first Tab and lands you in the main content.
- Sticky headers, footers and banners never entirely cover a focused control.
- No keyboard trap exists, and modal dialogs close with the keyboard.
- You repeated the check at a narrow window width and after the latest release.
Common mistakes to avoid
- Removing the outline globally. A line such as
*:focus { outline: none; }fails Focus Visible everywhere. Delete it, or replace it with a:focus-visiblestyle. - Using a
divorspanas a button or link. Switch tobuttonora href. - Setting positive
tabindexto fix order. Reorder the HTML. - Hiding the skip link with
display: none. It then never receives focus; move it off-screen and bring it in on:focus. - Testing only the home page. Forms, checkout, dialogs and error states hide more problems, as do third-party chat and consent widgets (see Third-Party Scripts and Performance for finding what loads on your pages).
- Trusting an automated score. Crawvix's accessibility checks are based on Lighthouse audits, which test things like names and contrast. Such tools cannot tell you whether the tab order makes sense or whether you can escape a widget.
Frequently asked questions
What keys should I use to test a website with the keyboard?
Tab moves forward, Shift+Tab moves back, Enter activates links and buttons, Space activates buttons and ticks checkboxes, arrow keys move within groups such as radio buttons and menus, and Escape closes pop-ups.
Do I need a visible focus outline on every element?
Every element a keyboard user can operate needs a visible focus mode. W3C says the browser's default indicator is acceptable if you leave it alone, and removing it without a replacement is a failure. A custom indicator should have at least 3:1 contrast against adjacent colors.
Is a skip link required by law?
This guide cannot give legal advice. WCAG 2.4.1 requires some way to bypass repeated blocks, and a skip link is one of several accepted techniques; headings and landmarks are others. Check the rules that apply to you in your country with a qualified adviser.
Does keyboard accessibility affect SEO?
This guide makes no ranking claim, and the sources below do not describe keyboard support as a search factor. The reasons to fix it are practical: more visitors can finish what they came to do, and native links and buttons carry built-in roles, as MDN notes. Pointer users have their own rule for small targets, covered in Mobile Usability: Fix Viewport, Tap Targets and Readable Text.
Related guides
- Website Accessibility Audit: Fix the Most Common Problems
- WCAG 2.2 Checklist: Level AA Items for Small Business Websites
- Accessible Forms: Labels, Instructions and Error Messages
- Color Contrast and WCAG: Ratios, Checks and Fixes
- Mobile Usability: Fix Viewport, Tap Targets and Readable Text
- How do I check if my website is accessible?
Official references
- https://www.w3.org/TR/WCAG22/
- https://www.w3.org/WAI/WCAG22/Understanding/keyboard.html
- https://www.w3.org/WAI/WCAG22/Understanding/no-keyboard-trap.html
- https://www.w3.org/WAI/WCAG22/Understanding/focus-visible.html
- https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html
- https://www.w3.org/WAI/WCAG22/Understanding/bypass-blocks.html
- https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible
- https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/tabindex
- https://web.dev/learn/accessibility/focus
Next step: Try the free website sample to see how your own site does on a few of these checks. This guide provides technical information, not a guarantee of rankings, traffic or index inclusion.
Crawvix Editorial Team
· Published November 4, 2026 · Last updated November 4, 2026 · 11 min read