← All criteria

Operable · Level AA · 2.5.7

Dragging Movements

Anything operated by dragging — reordering a list, a range slider, a carousel you swipe, a color picker you drag across — needs a single-pointer alternative that doesn't require holding down and moving at the same time: a tap, a click, a pair of buttons. This covers anyone who can't perform a precise press-hold-move-release sequence, whether that's a hand tremor, a trackball, an eye-gaze system, or a touchscreen with no keyboard to fall back on.

  • Motor

How to recognize it

Try to operate every draggable interaction using only single taps or clicks, with no holding and moving. A sortable list where picking an item up and dragging it to a new position is the only way to reorder it fails if there's no alternative. A range slider that only responds to dragging its handle — no arrow keys, no click-to-set — fails. A carousel that only advances by swipe with no visible previous/next buttons fails. Two things are explicitly out of scope, worth knowing so you don't over-apply this: the browser's own native page scrolling isn't covered (that's the user agent's responsibility, not the page author's), and if dragging is genuinely essential to what the interaction is — a freehand drawing tool, for instance — that's exempt too.

How to fix it

Add a single-pointer way to accomplish the same thing. For a sortable list, this is the exact same fix 2.1.1 needs for keyboard access: 'move up' / 'move down' buttons next to each item work for a mouse click, a screen tap, and a keyboard press all at once — one fix satisfies both criteria. For a range slider, use a real <input type="range"> instead of a custom drag-only widget; the native element gets click-to-set and arrow-key support for free. For a carousel, add visible previous/next buttons alongside the swipe gesture rather than relying on swipe alone.

Example

Avoid

<li draggable="true" ondragstart="handleDrag(event)">Item</li>
<div class="slider-handle" onmousedown="startDrag(event)"></div>
<!-- no click-to-set, no keyboard support -->
<div class="carousel" ontouchstart="startSwipe(event)">...</div>
<!-- no visible prev/next buttons -->

Prefer

<li draggable="true" ondragstart="handleDrag(event)">Item <button aria-label="Move item up">↑</button> <button aria-label="Move item down">↓</button></li>
<input type="range" min="0" max="100">
<div class="carousel">
  <button aria-label="Previous slide">&lsaquo;</button>
  ...
  <button aria-label="Next slide">&rsaquo;</button>
</div>

Resources