Common Violations

Keyboard Inaccessible Controls: Why 'Works With a Mouse' Isn't Enough

Try unplugging your mouse and navigating your site using only Tab, Shift+Tab, Enter, and the arrow keys. If you can't reach every interactive element, or can't tell where you are on the page, you've found a keyboard accessibility failure - and you've just experienced the site the way every keyboard-only user, every switch-device user, and every screen reader user does by default, since screen readers navigate through the same keyboard interface rather than a pointer.

Industry data puts keyboard inaccessibility at roughly 61% of ADA web accessibility complaints - the fourth most-cited issue, and one automated tools can only partially catch (WCAG Success Criterion 2.1.1, Keyboard, is a Category B "partially automatable" check: a scanner can flag suspicious patterns like a positive tabindex, but confirming full keyboard operability requires using the expected keyboard interactions throughout the page).

The most common failure patterns

A <div> or <span> styled to look like a button, with only an onclick handler. Mouse clicks fire it; Tab skips right past it, because a plain <div> isn't in the keyboard focus order and has no built-in Enter/Space activation.

<!-- Before: invisible to keyboard users -->
<div class="button" onclick="submitForm()">Submit</div>

<!-- After: a real button, focusable and Enter/Space-activatable for free -->
<button type="submit">Submit</button>

Custom dropdowns, modals, and menus built from scratch that only respond to mouseover/mouseout and never wire up keyboard events (Escape to close, arrow keys to move between options, Enter to select).

A visible focus indicator that's been removed. Even a fully keyboard-operable page fails in practice if outline: none (or similar) is applied globally with no replacement - a keyboard user can technically tab through the page but has no way to see where they are. This overlaps with WCAG 2.4.7 (Focus Visible).

Positive tabindex values (tabindex="1", tabindex="2", etc.) that try to manually control tab order - these almost always create a worse order than the natural DOM order they're overriding, and axe-core flags any positive tabindex for exactly this reason.

How to fix it

Prefer real, native interactive elements (<button>, <a href>, <input>, <select>) over recreating their behavior on generic elements - they come with keyboard support, focus management, and screen reader semantics built in, for free. This is the same "semantic HTML over ARIA" principle that applies across most accessibility fixes: don't rebuild what the platform already gives you correctly.

If a custom widget is unavoidable, implement the keyboard interactions for its role using the WAI-ARIA Authoring Practices keyboard guidance, with visible focus and a keyboard-accessible entry point. Composite widgets such as radio groups, tablists, menus and interactive grids typically have one Tab stop and use arrow keys internally. With roving tabindex, one item has tabindex="0" and the others have tabindex="-1"; move focus and update these values as the user navigates. Do not give every item a separate Tab stop or use positive tabindex values to force the order.

Official references

Common questions

How do I test for keyboard accessibility?
Unplug your mouse and navigate with Tab, Shift+Tab, Enter, Space, and the arrow keys. If you cannot reach a control, operate it, or see where focus is, that is a keyboard failure.
Why do div click handlers fail keyboard users?
A `<div>` or `<span>` with an `onclick` is not focusable or operable by keyboard by default. Use a native `<button>` or `<a>`, or add `tabindex`, a key handler, and the correct role - native elements are far safer.
Which WCAG rule covers keyboard access?
SC 2.1.1 (Keyboard), Level A, backed by 2.1.2 (No Keyboard Trap). Anything a mouse can do, a keyboard must be able to do too.

Check these issues on your own website

Start with a free one-page preview, with no account or payment required. For scheduled scans, issue history and team workflows, explore paid monitoring.