Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion public/.well-known/agent-skills/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"type": "skill-md",
"description": "Query and apply The Website Specification — a platform-agnostic specification of what a good website does. Use when the user asks what their site should have, whether something is required, how to audit a URL, what's missing for agent readiness, or anything else where you'd otherwise be guessing at web best practice. Backs answers with primary sources and ships an MCP server with search, list, fetch, checklist, and audit tools.",
"url": "/.well-known/agent-skills/specification-website/SKILL.md",
"digest": "sha256:17d9594c060aeb8ee300a09956e4893609ec8f14a971c68558bd0d0a1936c3a5"
"digest": "sha256:eee0e0eed9c58b7de016b1fbcf57589d3224c0a8d64e067e008dbfe1d25523c0"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Query and apply The Website Specification — a platform-agnostic s

# specification.website

The Website Specification is a single source of truth for what a good website does. Ten categories, 160 pages, every item tagged with a status. It ships in three machine-readable forms: per-page Markdown, llms.txt / llms-full.txt, and an MCP server.
The Website Specification is a single source of truth for what a good website does. Ten categories, 161 pages, every item tagged with a status. It ships in three machine-readable forms: per-page Markdown, llms.txt / llms-full.txt, and an MCP server.

## When to use this skill

Expand Down
Binary file modified public/og-default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/og/checklist.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/og/spec.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/og/spec/accessibility.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/content/changelog/2026-07-10-dragging-movements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: Dragging movements need a single-pointer alternative
date: "2026-07-10"
type: added
relatedSlugs: [dragging-movements, touch-target-size, keyboard-navigation]
---

Added a page on [dragging movements](/spec/accessibility/dragging-movements/), WCAG 2.2 Success Criterion 2.5.7. Sliders, sortable lists, drag-to-pan maps and swipe carousels each have to offer a route that a single pointer can walk without ever dragging, because a sustained, path-following press excludes people with tremor, switch users, and anyone driving the page with a head-pointer. The criterion does not ban drag and drop — it asks you to add the second route alongside it.
82 changes: 82 additions & 0 deletions src/content/spec/accessibility/dragging-movements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
title: "Dragging movements"
slug: dragging-movements
category: accessibility
summary: "Anything you can drag must also work with a single pointer that never drags. Sliders, sortable lists, and drag-to-pan maps each need a click or tap alternative."
status: recommended
order: 146
appliesTo: [all]
relatedSlugs:
[touch-target-size, keyboard-navigation, native-interactive-elements, mobile-form-inputs]
updated: "2026-07-10T00:00:00.000Z"
sources:
- title: "WCAG 2.5.7 — Dragging Movements (Level AA)"
url: "https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html"
publisher: "W3C"
- title: "WCAG 2.2 Recommendation"
url: "https://www.w3.org/TR/WCAG22/#dragging-movements"
publisher: "W3C"
- title: "WCAG 2.5.1 — Pointer Gestures (Level A)"
url: "https://www.w3.org/WAI/WCAG22/Understanding/pointer-gestures.html"
publisher: "W3C"
- title: "MDN — Pointer events"
url: "https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events"
publisher: "MDN"
---

## What it is

**Dragging Movements** is WCAG 2.2 Success Criterion 2.5.7, at **Level AA**. A dragging movement is any operation where the pointer presses down on one point, moves along a path while held, and releases somewhere else — dragging a slider thumb, reordering a list, panning a map, swiping a carousel.

The criterion says that all functionality using a dragging movement must also be achievable **with a single pointer that never drags**, unless dragging is essential or the behaviour belongs to the user agent rather than to you.

Three exceptions apply. Dragging may be **essential** — a drawing canvas or a signature field is the drag. The functionality may be **determined by the user agent and not modified by the author**, which exempts native scrollbars, touch scrolling, and the scrolling a browser supplies for a CSS `overflow` container. And a **path-based gesture** that traces a specific shape is governed by SC 2.5.1 Pointer Gestures instead.

### It does not ban drag and drop

The wrong belief to correct is that 2.5.7 outlaws dragging. It does not. Dragging is a fine interaction and most people like it. The criterion is purely **additive**: keep the drag, and add a second path to the same outcome that a single tap or click can walk. A sortable list that offers both drag handles and "move up" / "move down" buttons passes. A list that offers only the buttons also passes — but nobody asked you to remove the handles.

The other common confusion is with SC 2.5.1 Pointer Gestures. That criterion is about **multipoint or path-based** gestures — pinch-to-zoom, a two-finger swipe, tracing an L-shape. 2.5.7 is about the humble **single-pointer drag**. A control can fail one and pass the other, so check both.

## Why it matters

A drag is a sustained, precise, path-following press. It asks the user to keep contact while moving accurately, then release at exactly the right place. That combination excludes people who can point but cannot drag:

- Users with tremor, spasticity, or limited dexterity, for whom holding a press steady through a movement is unreliable.
- Users of head-pointers, eye-tracking, or mouth-sticks, where "press and hold while moving" is slow and error-prone.
- Switch-access users, who have no continuous pointer path at all.
- Anyone on a trackpad in a moving vehicle, or operating a touchscreen one-handed.

When the drag is the only route, these visitors are not merely inconvenienced — the feature is unreachable. If reordering your saved items or setting a price filter exists only as a drag, that function does not exist for them.

## How to implement

Start from the platform. `<input type="range">` already ships a non-dragging alternative: click anywhere on the track to jump the thumb there, and use the arrow keys once focused. A custom slider built from `<div>`s and `pointermove` handlers usually ships neither, which is how a passing control becomes a failing one.

Where you own the interaction, pair every drag with a click target:

- **Sliders and range controls.** Allow a click on the track to move the thumb. Add stepper buttons for fine adjustment where the range is wide.
- **Sortable lists.** Give each row "move up" and "move down" buttons, or a "move to…" control that opens a position picker. Keep the drag handle as well.
- **Maps and pannable canvases.** Provide directional arrow buttons and zoom `+` / `−` controls alongside drag-to-pan.
- **Carousels.** Provide previous / next buttons; do not rely on swipe alone.
- **Drop targets.** Offer a click-to-select, then click-to-place flow, or a plain file input beside the drag-and-drop zone.

Make the alternative a real, focusable control — a `<button>` — rather than a click handler bolted onto a `<div>`. That also satisfies [keyboard navigation](/spec/accessibility/keyboard-navigation/), which 2.5.7 does not itself require but which the same users usually need. Note that keyboard support alone does **not** satisfy this criterion: it is about the *pointer*, and a user with a head-pointer and no keyboard still needs a single-pointer route.

Size the alternative controls properly. A "move up" chevron that is 12 px square trades a dragging barrier for a [target-size](/spec/accessibility/touch-target-size/) one.

## Common mistakes

- A custom slider that only responds to `pointerdown` + `pointermove`, ignoring a plain click on the track.
- Drag-only reordering with no per-row move controls.
- A drag-and-drop upload zone with no file input behind it.
- Assuming keyboard operability is enough — the criterion is specifically about single-pointer use.
- Treating pinch-to-zoom as covered here; that is SC 2.5.1.
- Adding "move up" / "move down" buttons that are hidden until hover, so touch users never see them.

## Verification

- For every draggable control, complete the same task using only single clicks or taps — press and release in one spot, never moving while held. If you cannot, it fails.
- Test with the pointer only. Put the keyboard aside; keyboard access does not discharge this criterion.
- Check each alternative control is at least 24×24 CSS px and visible without hover.
- Confirm that anything you treat as exempt is genuinely essential (a drawing surface) or genuinely user-agent-supplied (a native scrollbar), and not simply convenient.
2 changes: 1 addition & 1 deletion src/content/spec/accessibility/keyboard-navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ summary: "Every interactive element on the page must be reachable and operable w
status: required
order: 40
appliesTo: [all]
relatedSlugs: [focus-indicators, skip-links, semantic-html, inert-attribute]
relatedSlugs: [focus-indicators, skip-links, semantic-html, inert-attribute, dragging-movements]
updated: "2026-05-29T09:13:20.000Z"
sources:
- title: "WCAG 2.1.1 — Keyboard (Level A)"
Expand Down
11 changes: 10 additions & 1 deletion src/content/spec/accessibility/native-interactive-elements.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ summary: "Prefer native HTML interactive elements — <button>, <a>, <details>/<
status: recommended
order: 155
appliesTo: [all]
relatedSlugs: [semantic-html, aria-usage, keyboard-navigation, hidden-until-found, inert-attribute, invoker-commands]
relatedSlugs:
[
semantic-html,
aria-usage,
keyboard-navigation,
hidden-until-found,
inert-attribute,
invoker-commands,
dragging-movements,
]
updated: "2026-07-08T00:00:00.000Z"
sources:
- title: "WHATWG HTML — The details element"
Expand Down
3 changes: 2 additions & 1 deletion src/content/spec/accessibility/touch-target-size.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ summary: "Interactive controls must be large enough to tap or click reliably. WC
status: required
order: 145
appliesTo: [all]
relatedSlugs: [keyboard-navigation, focus-indicators, empty-links-buttons, mobile-form-inputs]
relatedSlugs:
[keyboard-navigation, focus-indicators, empty-links-buttons, mobile-form-inputs, dragging-movements]
updated: "2026-06-08T00:00:00.000Z"
sources:
- title: "WCAG 2.5.8 — Target Size (Minimum) Level AA"
Expand Down
Loading