2.5.7 Dragging Movements

Level: AA | Principle: Operable | Since: WCAG 2.2 | Automation: Manual


What This Means

Any functionality that uses dragging (click-and-hold then move) must also be achievable through single-pointer actions without dragging — such as clicking buttons, using menus, or tapping targets. Dragging requires sustained, precise pointer control that many users cannot perform.

Who This Affects

  1. Motor impairment users — may lack the fine motor control to click, hold, and move simultaneously
  2. Tremor or spasticity users — dragging requires sustained steady control that tremors disrupt
  3. Head pointer / eye tracking users — drag gestures are extremely difficult with these input methods
  4. Touch screen users with limited dexterity — drag-and-drop on mobile is unreliable for many users

Common Pitfalls

1. Drag-and-drop reordering with no alternative

<!-- Bad: only way to reorder is drag-and-drop -->
<ul class="sortable">
  <li draggable="true">Item 1</li>
  <li draggable="true">Item 2</li>
  <li draggable="true">Item 3</li>
</ul>
<!-- No move-up / move-down buttons -->

2. Slider with no text input

<!-- Bad: only way to set value is dragging the thumb -->
<input type="range" min="0" max="100" />
<!-- No number input or step buttons -->

3. Kanban board with drag-only movement

Cards can only be moved between columns by dragging — no menu or button to select a destination column.

4. File upload that only accepts drag-and-drop

<!-- Bad: only drag-and-drop file upload -->
<div class="dropzone" ondrop="handleDrop(e)">
  Drag files here
</div>
<!-- No file input or browse button -->

How to Fix

Add move buttons to sortable lists

<ul class="sortable">
  <li>
    <span>Item 1</span>
    <button aria-label="Move Item 1 up" onclick="moveUp(0)">&#9650;</button>
    <button aria-label="Move Item 1 down" onclick="moveDown(0)">&#9660;</button>
  </li>
  <li>
    <span>Item 2</span>
    <button aria-label="Move Item 2 up" onclick="moveUp(1)">&#9650;</button>
    <button aria-label="Move Item 2 down" onclick="moveDown(1)">&#9660;</button>
  </li>
</ul>

Add number input alongside range slider

<label for="volume">Volume</label>
<input type="range" id="volume" min="0" max="100" value="50"
  oninput="volumeNumber.value = this.value" />
<input type="number" id="volumeNumber" min="0" max="100" value="50"
  oninput="volume.value = this.value" />

Add context menu to Kanban cards

<div class="card">
  <h3>Task: Fix login bug</h3>
  <!-- Drag works for mouse users -->
  <!-- Menu alternative for everyone else -->
  <select aria-label="Move to column" onchange="moveCard(this.value)">
    <option value="todo">To Do</option>
    <option value="progress" selected>In Progress</option>
    <option value="done">Done</option>
  </select>
</div>

Always pair drag-and-drop file upload with a file input

<div class="dropzone" ondrop="handleDrop(e)" ondragover="e.preventDefault()">
  <p>Drag files here or</p>
  <label for="file-input" class="browse-btn">Browse files</label>
  <input type="file" id="file-input" onchange="handleFiles(this.files)" />
</div>

How to Test

  1. Identify every drag interaction on the page: sortable lists, sliders, file upload drop zones, Kanban boards, color pickers, and map panning.
  2. For each drag interaction, look for a single-click or keyboard alternative: move up/down buttons for sortable lists, a number input for sliders, a file browse button for upload zones.
  3. Test each alternative to confirm it achieves the same result as dragging.
  4. Check that range sliders (<input type="range">) can be operated with arrow keys and optionally have a paired number input.
  5. Pass: Every drag-based interaction has a single-click or keyboard alternative that achieves the same result.
  6. Fail: Any functionality requires dragging with no single-pointer or keyboard alternative provided.

axe-core Rules

| Rule | What It Checks | |------|---------------| | — | No automated axe-core rule for this criterion. Drag alternatives require manual review. |

Sources

  1. W3C WCAG 2.2 — Understanding 2.5.7
  2. WCAG 2.2 What's New