Skip to main content
Operable WCAG 2.5.7

2.5.7 Dragging Movements

All functionality that uses a dragging movement for operation can be achieved by a single pointer without dragging, unless dragging is essential or the functionality is determined by the user agent.

Level AA Serious WCAG 2.2 (new)

What this rule means

WCAG 2.5.7 requires that any functionality requiring a dragging movement (pressing, holding, and moving a pointer) must also be operable through a single-pointer mechanism that does not require dragging. This means providing click/tap alternatives for drag-and-drop, slider adjustments, sortable lists, and other drag-dependent interactions.

A dragging movement involves pressing a pointer button (or touching), holding it down, and moving to a new position. The alternative must allow the same outcome through discrete pointer actions — such as clicking a start point, then clicking an end point, or using increment/decrement buttons.

Why it matters

Dragging requires sustained pointer contact along a precise path, which many users cannot perform. Users with tremors, limited grip strength, or motor impairments may not be able to maintain pointer-down pressure while moving. Users operating via eye-tracking, head-tracking, or mouth sticks often cannot perform drag operations at all.

Speech recognition users also struggle with drag interactions because voice commands typically activate discrete click/tap actions rather than continuous drag movements. Providing non-drag alternatives ensures that all users can complete tasks regardless of their motor capabilities.

Related axe-core rules

There are no automated axe-core rules for this criterion. Detecting drag-dependent functionality requires manual testing and code review to identify elements using drag-related events (dragstart, dragover, drop) or pointer move tracking.

How to test

  1. Identify all drag-and-drop interactions (sortable lists, file upload areas, sliders, kanban boards, drawing canvases).
  2. For each draggable feature, attempt to complete the same task without performing a drag motion.
  3. Verify that click/tap-based alternatives exist (buttons, menus, input fields).
  4. Test with keyboard-only navigation to confirm drag operations have keyboard equivalents.
  5. Use assistive technology pointer emulators that cannot perform drag operations.

How to fix

Provide single-pointer alternatives for all drag-based interactions.

Sortable list — drag only (bad)

<!-- Only drag-and-drop to reorder, no alternatives -->
<ul id="sortable">
  <li draggable="true" ondragstart="drag(event)">Item 1</li>
  <li draggable="true" ondragstart="drag(event)">Item 2</li>
  <li draggable="true" ondragstart="drag(event)">Item 3</li>
</ul>

Sortable list — with button alternatives (good)

<ul id="sortable" role="list">
  <li draggable="true">
    <span>Item 1</span>
    <div class="reorder-controls">
      <button aria-label="Move Item 1 up" onclick="moveUp(this)">
        &#x25B2;
      </button>
      <button aria-label="Move Item 1 down" onclick="moveDown(this)">
        &#x25BC;
      </button>
    </div>
  </li>
  <li draggable="true">
    <span>Item 2</span>
    <div class="reorder-controls">
      <button aria-label="Move Item 2 up" onclick="moveUp(this)">
        &#x25B2;
      </button>
      <button aria-label="Move Item 2 down" onclick="moveDown(this)">
        &#x25BC;
      </button>
    </div>
  </li>
</ul>

Slider with input alternative

<!-- Draggable slider with number input alternative -->
<div class="slider-container">
  <label for="price-slider">Maximum price</label>
  <input type="range" id="price-slider" min="0" max="500"
    value="250" step="10">
  <input type="number" id="price-input" min="0" max="500"
    value="250" step="10" aria-label="Maximum price value">
</div>

<script>
  const slider = document.getElementById('price-slider');
  const input = document.getElementById('price-input');
  slider.addEventListener('input', () => input.value = slider.value);
  input.addEventListener('input', () => slider.value = input.value);
</script>

File upload — drop zone with button fallback

<div class="drop-zone"
  ondragover="event.preventDefault()"
  ondrop="handleDrop(event)">
  <p>Drag files here to upload</p>
  <!-- Non-drag alternative -->
  <label for="file-upload" class="upload-button">
    Or click to select files
  </label>
  <input type="file" id="file-upload" multiple
    onchange="handleFiles(this.files)" class="visually-hidden">
</div>

Common mistakes

  • Sortable lists or kanban boards that only support drag-and-drop reordering with no button or menu alternative.
  • Custom sliders that only respond to dragging the thumb, without keyboard arrow key support or a numeric input.
  • File upload zones that only accept drag-and-drop without a file picker button.
  • Image cropping or positioning interfaces that require dragging without coordinate input fields.
  • Drawing or annotation tools with no structured input alternative for users who cannot drag.

Resources