Custom widgets that bind actions to pointerdown, mousedown, or touchstart fire the moment a finger lands -- so an accidental touch during scrolling or rest triggers the action with no chance to slide off and cancel
2.5.2 Pointer Cancellation
In Plain Language
2.5.2 Pointer Cancellation (Level A, new in WCAG 2.1) says functions triggered by a single-pointer DOWN event must satisfy at least one of four options[1]: (a) no down-event activation -- the function fires on the UP event instead; (b) abort or undo -- the function can be cancelled before completion or undone after; (c) up reversal -- the pointer-up event reverses the down-event outcome; or (d) essential -- down-event activation is intrinsic to the function (a piano keyboard app where the note must sound the moment the key is pressed).
The native HTML click event on <button> and <a> fires on pointer-up after a matching pointer-down on the same target, which satisfies option (a) automatically. Custom widgets that bind behavior to pointerdown, mousedown, or touchstart skip that safeguard and have to implement one of the other options themselves.
Why It Matters
- Users with tremor, spasticity, or limited fine motor control often touch the screen accidentally during scrolling, navigation, or while resting a hand on a device. If the function fires on touchdown, an accidental contact triggers an irreversible action -- deleting a record, sending a message, placing an order -- before the user can react.
- The fix is mechanical: fire on touchup instead of touchdown. That gives the user the chance to slide off the target before lifting their finger, turning an accidental press into a non-event.
- Switch devices, head pointers, and eye-gaze systems can emit stray down-events as part of their normal operation. Deferring activation to the up-event filters those out.
- Non-disabled users rely on the same safety net. Anyone who has started to click a destructive button and then slid off to cancel is using the down-then-up-on-same-target contract that
clickenforces.
Examples
✔ Action fires on click (pointer up). User can press down, slide away, and release to cancel.
<!-- click fires on pointer up after a matching
pointer down on the same target -->
<button onclick="deleteItem()">Delete item</button>
<!-- Press, slide away, release -- no delete. -->
✘ Action fires immediately on pointer down. No chance to cancel by moving away.
<!-- Fails 2.5.2: fires on the down-event with no
abort, no undo, and no up-reversal -->
<button onmousedown="deleteItem()">Delete item</button>
☰
✔ Down-event starts the drag, but releasing outside the drop zone returns the item to its original position (up-event reverses the down-event).
<!-- Drag starts on pointerdown. Releasing outside
a valid drop zone returns the item to origin,
satisfying the up-reversal option. -->
<div draggable="true"
ondragend="if (!dropped) resetPosition()">
Drag me
</div>
✘ Form submits the instant a finger touches the button. Accidental touches cannot be recovered.
How to Fix It
- Bind to
click, not to down-events. The nativeclickevent fires on pointer-up after a matching pointer-down on the same element, so it satisfies option (a) without any extra work. Avoidmousedown,touchstart, andpointerdownas activation triggers for custom widgets. - Use
<button>and<a>where you can. Both elements wire up the down-then-up-on-same-target contract by default. A<div role="button">that only listens topointerdowninherits none of that. - For drag-and-drop, reverse on release outside the target. If the down-event starts a drag, releasing outside a valid drop zone must return the element to its starting position. That satisfies option (c), up-reversal.
- If down-event activation is unavoidable, provide abort or undo. Option (b) covers cases where a pointer-down triggers something for responsiveness -- supply an abort (confirmation dialog before completion) or an undo (toast with a reversal action) so the user can recover.
- Use the essential exception narrowly. Option (d) is for interactions where timing on the down-event is intrinsic -- piano keyboards, drum pads, some game controls. Buttons, links, and form controls are not essential exceptions.
- Test by press-and-slide. For every interactive element, press down, move the pointer off the target, then release. The action must not fire. If it fired, the widget is listening to the wrong event.
References
- [1] W3C (2023). Understanding Success Criterion 2.5.2: Pointer Cancellation. W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/pointer-cancellation.html ↩