F54: When Mouse-Only Code Locks Out Keyboard Users
Marcus · AI Research Engine
Analytical lens: Operational Capacity
Digital accessibility, WCAG, web development
AI-assisted · Source-linked · Editorially reviewed · Methodology
Trust note
This article was drafted with AI assistance, reviewed against accessibility.chat editorial standards, and should be treated as research and education rather than legal advice. We prioritize primary sources and correct material errors.

2004: WCAG 1.0 already required keyboard access. 2008: WCAG 2.0 formalized it under Success Criterion 2.1.1. 2018: WCAG 2.1 extended coverage to touch and gesture. 2023: WCAG 2.2 published. And still, Failure F54 (opens in new window) — mouse-only event handlers as the sole mechanism for a function — remains one of the most documented patterns in the accessibility failure catalog.
That timeline isn't an indictment of any single team. It reflects something structural: pointer-device events are the default mental model in most frontend development workflows. You reach for onclick, onmousedown, onmouseover because they work for the majority of users and the browser cooperates immediately. The keyboard path requires deliberate, additional thought. F54 exists because that asymmetry produces real exclusion.
The Failure
F54 describes a specific, testable pattern: a function is accessible only through a pointing-device event handler — mouse, trackpad, stylus, or touch gesture — with no equivalent keyboard mechanism provided.
The official W3C document (opens in new window) gives a precise example:
<p><img onmousedown="nextPage();" src="nextarrow.gif" alt="Go to next page"></p>This image triggers navigation on mousedown. A keyboard user tabs to it — if they can tab to it at all, since <img> elements aren't natively focusable — and pressing Enter does nothing. The onmousedown handler simply never fires from a keyboard event. The function is invisible to anyone not using a pointing device.
The governing standard is WCAG 2.1.1 Keyboard (opens in new window), which requires that all functionality be operable through a keyboard interface, except where the underlying function requires path-dependent pointer movement (freehand drawing, for instance). Navigation to a next page is not path-dependent. There's no exception that applies.
Why This Matters
The affected population is broader than most developers initially assume.
Screen reader users navigate almost entirely by keyboard. A mouse-only trigger is simply absent from their interaction model — it doesn't exist in the tab order, it doesn't respond to Enter or Space, and screen reader virtual cursor navigation won't activate it either.
Motor-disabled users who rely on switch access, sip-and-puff devices, or alternative keyboards depend on keyboard-equivalent events. These devices emulate keyboard input at the OS level. If the event handler only responds to pointer coordinates, the emulation fails silently.
Power keyboard users — a significant portion of the general population — expect Tab, Enter, and arrow keys to work everywhere. Mouse-only interactions break that expectation and create friction even for users without disabilities.
The W3C's framing is precise: users "with no vision (who cannot use devices such as mice that require eye-hand coordination) as well as users who must use alternate keyboards or input devices that act as keyboard emulators will be unable to access the function." That's not a narrow edge case. That's a substantial slice of users encountering a complete dead end.
From an operational standpoint, this failure also has a compounding quality. One mouse-only image might be an isolated bug. A pattern of onmousedown, onmouseover, and ondblclick handlers wired to custom components throughout an application signals something deeper: keyboard accessibility wasn't part of the design contract at all. Our research on testing methodology shows that automated tools catch only a fraction of real barriers — and F54 failures are often in that uncaught fraction, because detecting "no keyboard equivalent exists" requires understanding functional intent, not just parsing markup.
The Fix
The source material's failing example uses <img> with onmousedown. The correction operates on two levels: semantic structure and event handling.
Corrected pattern:
<!-- Use a native interactive element --><a href="next-page.html"> <img src="nextarrow.gif" alt="Go to next page"></a><!-- Or, if JavaScript navigation is required --><button type="button" onclick="nextPage();"> <img src="nextarrow.gif" alt="Go to next page"></button>Native <a> and <button> elements are focusable by default, respond to Enter (and Space for buttons), and activate onclick from both pointer and keyboard events. That's the key insight: onclick in modern browsers fires on keyboard activation of focusable elements. onmousedown does not.
If a custom element must be used and pointer-specific events are genuinely needed for pointer-specific behavior, pair them with keyboard equivalents:
<div role="button" tabindex="0" onmousedown="nextPage();" onkeydown="if(event.key === 'Enter' || event.key === ' ') nextPage();"> <img src="nextarrow.gif" alt="Go to next page"></div>This approach satisfies 2.1.1, but the native element solution is always preferable. Custom ARIA roles require more maintenance, more testing, and more can go wrong. The ARIA Authoring Practices Guide (opens in new window) documents the full keyboard interaction patterns required for each role — role="button" alone isn't enough if the keydown handling is incomplete.
Applying This
F54 failures are catchable at multiple points in a development workflow, but they require different tools at each stage.
In code review, flag any event handler that uses onmousedown, onmouseover, onmouseenter, onmouseleave, or touch-specific events (ontouchstart, ontouchend) on non-interactive elements, or as the sole handler for a function. The question to ask: "Can a keyboard user trigger this?" If the answer requires checking the element type and the event list simultaneously, make that a checklist item.
In automated testing, tools like axe-core and Lighthouse will catch some instances — particularly non-focusable elements with event handlers — but they won't reliably detect cases where a focusable element has mouse-only handlers and no keyboard equivalent. This is precisely the detection gap documented in our research on automated vs. manual testing. Manual keyboard testing — Tab through every interactive element, activate with Enter and Space, verify the function executes — remains the reliable check.
In design systems, the fix is upstream: establish a component library where every interactive pattern uses native elements or fully keyboard-accessible ARIA implementations by default. When the design system handles it correctly, individual developers don't have to remember.
| Event Handler | Keyboard Accessible? | Recommended Alternative |
|---|---|---|
onmousedown | No | onclick on <button> or <a> |
onmouseover | No | onfocus + onmouseover |
onmouseenter | No | onfocus + onmouseenter |
ondblclick | No | Single onclick with keyboard handler |
onclick on <div> | No (not focusable) | onclick on <button> with tabindex |
onclick on <button> | Yes | — |
onclick on <a href> | Yes | — |
CORS Perspective
Through an operational lens, F54 is a workflow problem masquerading as a code problem. The failure pattern emerges when keyboard accessibility isn't part of the definition of "done" — when developers test features by clicking, designers prototype with mouse interactions, and QA validates visual behavior without a keyboard in hand. Addressing F54 at scale means embedding keyboard testing into sprint cycles, adding pointer-event scrutiny to code review checklists, and ensuring design system components handle keyboard interaction before they ship — not after a complaint surfaces. The compliance framework research we've published shows that organizations making durable accessibility progress treat these as process changes, not one-time fixes. F54 is old enough to vote. The fact that it persists is a signal about process, not about complexity.
About the Marcus lens
An operational lens on digital accessibility. Frames findings around what implementation and maintenance actually require — WCAG conformance, engineering effort, and day-to-day web development practice.
Marcus is an AI analyst lens, not a human staff member. It helps frame this article through a consistent accessibility perspective.
Specialization: Digital accessibility, WCAG, web development
View all articles using this lens →Primary source reviewed: https://www.w3.org/WAI/WCAG22/Techniques/failures/F54 (opens in new window)
Transparency Disclosure
This article was drafted with AI assistance and reviewed against our editorial methodology. We disclose that process so readers can judge the work clearly.