2.5.2 Level A Guideline 2.5 Input Modalities Added in WCAG 2.1 Not detectable automatically

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.

In the specification