2.5.1 Pointer Gestures
Level: A | Principle: Operable | Since: WCAG 2.1 | Automation: Manual
What This Means
Any functionality that requires multipoint gestures (pinch-to-zoom, two-finger scroll) or path-based gestures (swiping, dragging a specific path) must also be operable with a single-pointer action (tap, click, long press) — unless the multipoint or path-based gesture is essential to the function.
Who This Affects
- Motor impairment users — may only be able to use a single finger, stylus, or head pointer
- Switch device users — input is limited to simple clicks or taps
- Voice control users — voice commands map to single-point actions, not complex gestures
- Elderly users — fine motor control makes multipoint gestures difficult or impossible
Common Pitfalls
1. Pinch-to-zoom with no button alternative
<!-- Bad: only way to zoom is pinch gesture -->
<div class="map" ongesturechange="handlePinchZoom(e)">
<!-- map content -->
</div>
<!-- Good: pinch works AND buttons are available -->
<div class="map" ongesturechange="handlePinchZoom(e)">
<!-- map content -->
</div>
<button onclick="zoomIn()">Zoom In (+)</button>
<button onclick="zoomOut()">Zoom Out (-)</button>
2. Swipe-only carousel
<!-- Bad: only swiping navigates slides -->
<div class="carousel" ontouchstart="..." ontouchmove="...">
<div class="slide">Slide 1</div>
<div class="slide">Slide 2</div>
</div>
<!-- Good: swipe works AND buttons exist -->
<div class="carousel">
<button aria-label="Previous slide" onclick="prevSlide()">←</button>
<div class="slide">Slide 1</div>
<div class="slide">Slide 2</div>
<button aria-label="Next slide" onclick="nextSlide()">→</button>
</div>
3. Path-based drawing as the only input
A signature pad that requires drawing a path with no alternative input method (typing name, uploading image).
4. Multi-finger rotation gesture
A photo editor that only supports two-finger rotation with no rotation button or angle input.
How to Fix
Always provide single-pointer alternatives
For every multipoint or path-based gesture, add a clickable/tappable control:
| Gesture | Single-Pointer Alternative | |---------|---------------------------| | Pinch to zoom | + / - buttons | | Swipe to navigate | Previous / Next buttons | | Two-finger rotate | Rotate button or angle input | | Drag path to draw | Click-to-place points or type coordinates | | Multi-finger scroll | Standard scrollbar or scroll buttons |
Example: Map with zoom controls
<div class="map-container">
<div id="map"></div>
<div class="map-controls">
<button aria-label="Zoom in" onclick="map.zoomIn()">+</button>
<button aria-label="Zoom out" onclick="map.zoomOut()">-</button>
<button aria-label="Reset view" onclick="map.reset()">Reset</button>
</div>
</div>
Exception
The gesture is essential when no single-pointer alternative can achieve the same result — for example, freehand drawing in an art application where the path itself is the content.
How to Test
- Identify every interaction on the page that uses multipoint gestures (pinch-to-zoom, two-finger scroll) or path-based gestures (swiping, dragging a specific path).
- For each gesture, look for a single-pointer alternative: buttons (zoom in/out, next/previous), tap targets, or click-based controls.
- Test using only a single finger or pointer. Confirm all functionality that works with gestures also works with single taps or clicks.
- Check carousels for Previous/Next buttons, maps for zoom +/- buttons, and image galleries for single-tap navigation.
- Pass: Every multipoint or path-based gesture has a single-pointer alternative (button, tap, or click).
- Fail: Any functionality requires a multipoint or path-based gesture with no single-pointer alternative.
axe-core Rules
| Rule | What It Checks | |------|---------------| | — | No automated axe-core rule for this criterion. Gesture alternatives require manual review. |