Pointer Cancellation
For functionality operated by a single pointer, the action completes on the up-event, or can be aborted or undone.
Who this affects
Users with tremor or imprecise pointing who land on the wrong control and need to slide off before releasing to cancel. Firing on mousedown removes that safety net.
The failure and the fix
Each example below is a self-contained page, loaded in a frame so its markup cannot affect this page. Open either one on its own to test it with a keyboard or screen reader.
Fails 2.5.2
Open the failing example in a new tab
fail.html — the problem
<h1>Your account</h1>
<!-- FAILURE: the action fires on the DOWN event. The moment the pointer
touches the control, the account is deleted.
Why the up-event matters: everyone occasionally presses the wrong thing.
Firing on up gives you the universal escape - slide off the control before
letting go and nothing happens. Users with tremor or imprecise pointing
rely on that escape constantly. Firing on down removes it, and here it
removes it from an irreversible action. -->
<button type="button" class="button" id="del"
onpointerdown="deleteAccount()">Delete my account</button>
<p id="log" role="status"></p>
Meets 2.5.2
Open the passing example in a new tab
pass.html — the fix
<h1>Your account</h1>
<!-- FIX: use click. The browser's click event only fires when the pointer goes
down AND comes back up on the same element, so sliding off to cancel works
for free. This is another case where the platform default is already
correct and the failure comes from replacing it.
2.5.2 offers four ways to conform - no down-event activation, or the
action can be aborted, or it can be undone, or the down-event is essential
(a piano key, a game control). Plain click gives you the first. -->
<button type="button" class="button" id="del">Delete my account</button>
<p id="log" role="status"></p>
<!-- Belt and braces: because deleting an account is irreversible, it also gets
a confirmation step. That is 3.3.4 Error Prevention, a different criterion
- but the two work together, and consequential actions want both. -->
<div id="confirm" hidden>
<p><strong>Delete your account permanently?</strong> This cannot be undone.</p>
<button type="button" class="button" id="yes">Yes, delete my account</button>
<button type="button" class="button button--secondary" id="no">Cancel</button>
</div>
How to test it
Press down on a control, move the pointer away, and release. The action must not fire. Look for handlers bound to mousedown, touchstart, or pointerdown that trigger the action directly.
-
Automated
Requires reading event bindings or performing the press-and-drag-away test.
No axe rule maps to this criterion. It has to be checked by a person.
-
Keyboard
Unplug the mouse. Move through the page with Tab, Shift+Tab, Enter, Space and the arrow keys. See the keyboard testing script.
-
Screen reader
Listen to both examples with NVDA, JAWS, VoiceOver or TalkBack and compare what is announced. See the screen reader cheat sheets.
-
Visual
Zoom to 200% and 400%, narrow the viewport to 320 px, and apply the text-spacing overrides. See the visual testing procedures.
Related criteria
In the specification
- Understanding 2.5.2 Pointer Cancellation — the W3C explanation, intent and exceptions
- 2.5.2 in the WCAG 2.2 Recommendation — the normative wording
WCAG 2.2 Demo Suite