Click handler without keyboard equivalent
keyboard/pointer-only
- WCAG success criterion
- 2.1.1 (level A)
- Outcome class
- Hint only. An automated check that by design reports review hints only: its findings are marked for manual review, never as confirmed violations.
- Area
- Accessibility, Navigation & Operation
- Default severity
- high
- axe-core rule
click-events-have-key-events
Why we flag this
Keyboard users cannot trigger the function.
onclick on a <div>/<span> without onkeydown/onkeyup, tabindex, or a matching role.
What the rule checks
Scope. Rendered elements that look clickable (computed cursor: pointer or an onclick attribute) and are not controls themselves.
Expectation. needs_review once per element where a pointer cursor starts (not where it is inherited) on an element with text that is no control, has no role or tabindex, and contains no control: if it does something, the keyboard cannot reach it. Not reported: the card pattern (cursor on a box around a link), real controls with a pointer cursor, descendants inheriting the cursor, elements already reported by keyboard/click-handler-not-focusable, and elements not rendered. A cursor set only by a media query on the phone viewport, or by script after load, counts.
Source. WCAG 2.2 SC 2.1.1 Keyboard and SC 4.1.2 Name, Role, Value
Detection: shared; needs dom, computed_style.
Failing example
The check flags this for review. Corpus case pointer_only, element div#search. The page may contain further findings for other rules.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Pointer-only corpus case</title>
<style>
.clicky { cursor: pointer; padding: 8px; width: 120px; }
.card { cursor: pointer; padding: 8px; }
</style>
</head>
<body>
<main>
<h1>Elements that look clickable</h1>
<!-- needs_review: looks clickable (cursor: pointer), no role, no tabindex, no control inside -->
<div class="clicky" id="search">Search</div>
<!-- absent: the card pattern — the whole card has cursor: pointer, the link inside is
the keyboard route (bundesregierung.de teasers, barrierlab#49) -->
<div class="card" id="card">
<h2><a href="/article">Article title</a></h2>
<p>Teaser text for the article.</p>
</div>
</main>
</body>
</html>Passing example
The check reports nothing here. Corpus case pointer_only, element div#card. The page may contain further findings for other rules.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Pointer-only corpus case</title>
<style>
.clicky { cursor: pointer; padding: 8px; width: 120px; }
.card { cursor: pointer; padding: 8px; }
</style>
</head>
<body>
<main>
<h1>Elements that look clickable</h1>
<!-- needs_review: looks clickable (cursor: pointer), no role, no tabindex, no control inside -->
<div class="clicky" id="search">Search</div>
<!-- absent: the card pattern — the whole card has cursor: pointer, the link inside is
the keyboard route (bundesregierung.de teasers, barrierlab#49) -->
<div class="card" id="card">
<h2><a href="/article">Article title</a></h2>
<p>Teaser text for the article.</p>
</div>
</main>
</body>
</html>This page is generated from the rule catalogue and the rule contracts; see therule overview for how the outcome classes are derived.