Level A

Motion-actuated features that ship without a UI equivalent lock out users whose devices are wheelchair-mounted or desk-resting, and fire constantly for users with tremors who cannot hold a device still.

2.5.4 Motion Actuation

In Plain Language

2.5.4 Motion Actuation (Level A, introduced in WCAG 2.1) applies whenever functionality is triggered by device motion (shaking, tilting, rotating) or by user motion sensed through the device (waving at a camera, gesturing). Two things are required: the same functionality must also be operable through standard user-interface components (buttons, menus, inputs), and the motion-triggered path must be possible to disable so accidental movement does not fire it[1].

Two exceptions exist. Motion used through an accessibility-supported interface -- for example, the operating system's own shake-to-undo gesture exposed as an assistive-technology hook -- does not need a separate alternative. Motion that is essential to the function, such as a pedometer or a virtual-reality head-tracker, is also exempt because no UI button can substitute for the sensor reading.

Why It Matters

  • A phone mounted to a wheelchair, tablet arm, or desk stand cannot be shaken or tilted. Every motion-only feature on that device is unreachable until a UI control exists that calls the same function.
  • Tremor, dystonia, and spasticity produce continuous involuntary motion. A "shake to undo" handler with no disable toggle triggers on every tremor cycle, so the user's destructive-action history is erased without intent.
  • Switch, head-pointer, and eye-tracking users route all input through one non-motion channel -- switches, dwell clicks, sip-and-puff. The devicemotion and deviceorientation events never fire for them, so a motion-gated feature is not slow, it is absent.
  • The failure is mechanistic, not statistical: any handler bound to devicemotion, deviceorientation, or a camera-based gesture stream without a parallel UI control and an off switch fails 2.5.4 by construction.

Examples

Do: Provide a button alternative for shake-to-undo

Shake your device to undo, or use the button:

✔ Motion shortcut has a UI alternative. Users who cannot shake the device can still undo.

<!-- Motion shortcut with a UI alternative -->
<p>Shake your device to undo, or use the button:</p>
<button onclick="undoAction()">Undo</button>

<script>
  // Motion listener calls the same function
  window.addEventListener('devicemotion', (e) => {
    if (isShake(e)) undoAction();
  });
</script>
Don't: Motion-only interaction with no alternative

Shake your device to refresh the feed.

✘ No button or other UI control to refresh. Users who cannot shake the device are stuck with stale content.

<!-- BAD: motion is the only way to refresh -->
<p>Shake your device to refresh the feed.</p>

<script>
  window.addEventListener('devicemotion', (e) => {
    if (isShake(e)) refreshFeed();
  });
  // No button alternative exists
</script>
Do: Allow users to disable motion responses

✔ Users can disable motion responses in settings. People with tremors will not accidentally trigger scrolling.

<!-- Setting to disable motion responses -->
<label>
  <input type="checkbox" id="motionToggle" checked>
  Enable tilt-to-scroll
</label>

<script>
  const toggle = document.getElementById('motionToggle');
  window.addEventListener('deviceorientation', (e) => {
    if (!toggle.checked) return; // Motion disabled
    handleTilt(e);
  });
</script>
Don't: No way to disable motion with no UI fallback

Tilt your device to navigate between photos.

✘ No setting to disable tilt navigation and no swipe or button alternative. Users with involuntary movements will constantly trigger unintended navigation.

How to Fix It

  1. Route the motion handler and the UI control through the same function. Define the action once (undoAction(), refreshFeed(), nextPhoto()) and call it from both the devicemotion listener and a <button>. Do not duplicate logic -- divergence is how the UI path quietly breaks while the motion path keeps working.
  2. Ship a user-visible setting that disables motion triggers. A toggle in app settings that removes or short-circuits the motion listener satisfies the "disable" half of 2.5.4. The OS-level prefers-reduced-motion media query is about animation, not input actuation, and does not substitute for an in-app off switch -- honour it for animation work, but add the explicit motion-input toggle anyway.
  3. Audit every devicemotion, deviceorientation, and camera-gesture listener. Grep the codebase for addEventListener('devicemotion', addEventListener('deviceorientation', and any getUserMedia-fed gesture pipeline. For each hit, confirm a parallel UI component calls the same function and a disable path exists.
  4. Test with the device flat on a desk. Put the phone down and try to complete every task. Anything that requires lifting, tilting, or shaking the device is a 2.5.4 failure in the making and needs a UI equivalent before the feature ships.
  5. Treat motion as a progressive enhancement, not a primary input. Build the UI control first, wire it to the action, then layer the devicemotion listener on top as a shortcut. Features designed motion-first tend to ship with a retrofitted button that only covers the happy path.
  6. Apply the exceptions narrowly. Motion is exempt only when it flows through an accessibility-supported interface (an OS gesture the AT layer can intercept) or when it is essential to the function -- a pedometer, a spirit level, a VR head-tracker. "Users expect to shake" is not essential; it is a design choice with a UI alternative.

References

  1. [1] W3C (2023). Understanding Success Criterion 2.5.4: Motion Actuation. W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/motion-actuation.html