Level AAA

Parallax backgrounds and scroll-linked transforms trigger vection illusions that activate motion-sickness pathways in users with vestibular disorders

2.3.3 Animation from Interactions

In Plain Language

[2.3.3 Animation from Interactions, Level AAA, new in WCAG 2.1[1]] requires that motion animation triggered by a user interaction -- parallax scrolling, slide-in transitions, page-flip effects, scroll-jacking -- can be disabled, unless the animation is essential to the functionality or information being conveyed.

The scope is user-triggered motion specifically. Animations that start on their own and keep running fall under 2.2.2 Pause, Stop, Hide[2]; 2.2.2 is about user-controlled pause of auto-playing motion, while 2.3.3 is about letting users opt out of motion that fires in response to scroll, click, or hover.

Why It Matters

  • Users with vestibular disorders -- benign paroxysmal positional vertigo (BPPV), vestibular migraine, Meniere's disease -- experience nausea, dizziness, and disorientation from large-scale motion on screen. The W3C Understanding document notes the reaction can be severe enough to require bed rest to recover[1].
  • Parallax scrolling is the most common trigger. The difference in velocity between foreground and background layers produces a vection illusion -- the visual system interprets the moving field as self-motion, activating the same neural pathways as physical motion sickness.
  • The "essential" exception is narrow. An animation is essential when removing it would change the information or break the function: a drag preview that follows the pointer, a progress indicator that shows work happening, the animation preview in an animation tool. Decorative slide-ins, scroll-linked zooms, and parallax backgrounds do not qualify.
  • When motion cannot be disabled, affected users close the tab. The cost of the decorative flourish is the loss of the entire page.

Examples

Do: Respect prefers-reduced-motion for scroll animations

Scroll-triggered fade-in with reduced-motion override:

@media (prefers-reduced-motion: reduce) {

  .reveal { animation: none; opacity: 1; }

}

✔ Users who enable reduced motion see content immediately without animation

<style>
  .reveal {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.6s ease, transform 0.6s ease;
  }
  .reveal.visible {
    opacity: 1;
    transform: translateY(0);
  }

  /* Disable motion for users who prefer it */
  @media (prefers-reduced-motion: reduce) {
    .reveal {
      animation: none;
      transition: none;
      opacity: 1;
      transform: none;
    }
  }
</style>

<div class="reveal">
  Content fades in on scroll -- or appears
  instantly when reduced motion is enabled.
</div>
Do: Provide a site-level toggle to disable animations

Settings panel with animation toggle:

<label>

  <input type='checkbox' id='reduce-motion'>

  Reduce motion

</label>

✔ Users can disable interaction-triggered animations directly in the site

<!-- Site-level toggle for users without OS-level setting -->
<label class="motion-toggle">
  <input type="checkbox" id="reduce-motion">
  Reduce motion
</label>

<script>
  const checkbox = document.getElementById('reduce-motion');
  checkbox.addEventListener('change', () => {
    document.documentElement.classList.toggle(
      'no-motion', checkbox.checked
    );
  });
</script>

<style>
  .no-motion *,
  .no-motion *::before,
  .no-motion *::after {
    animation-duration: 0s !important;
    transition-duration: 0s !important;
  }
</style>
Don't: Use parallax scrolling with no way to disable it

Parallax background that moves as the user scrolls:

background-attachment: fixed;

/* No reduced-motion override */

✘ Parallax motion is triggered by scrolling and cannot be disabled -- fails 2.3.3

Don't: Animate page elements on hover with no opt-out

Cards that zoom and rotate on hover:

.card:hover { transform: scale(1.1) rotate(2deg); }

/* No prefers-reduced-motion check */

✘ Hover-triggered motion animation with no way to turn it off fails 2.3.3

How to Fix It

  1. Gate motion on prefers-reduced-motion. The CSS media query prefers-reduced-motion: reduce reflects the OS-level setting (macOS: System Settings > Accessibility > Display > Reduce motion; Windows 11: Settings > Accessibility > Visual effects > Animation effects; iOS/Android have equivalents). Default to no motion and opt in with @media (prefers-reduced-motion: no-preference) { ... }, or default to motion and override inside @media (prefers-reduced-motion: reduce) { ... }. Either pattern satisfies 2.3.3 as long as the reduced-motion branch actually stops the transform.
  2. Provide an in-page toggle too. Users on shared machines, kiosks, or locked-down corporate builds cannot always set the OS preference. A visible "reduce motion" control that toggles a class on <html> gives them a direct override.
  3. Audit scroll-linked transforms. Parallax backgrounds (background-attachment: fixed with layered movement), scroll-driven transform: translate3d(), IntersectionObserver-triggered slide-ins, and the CSS scroll-timeline / animation-timeline: scroll() APIs all produce interaction-triggered motion. Each one needs a reduced-motion branch.
  4. Replace motion, do not just slow it. Setting transition-duration: 0s or animation: none and jumping to the end state is the correct behaviour. Slowing an animation from 600ms to 200ms still produces vection.
  5. Preserve essential animation. A pointer-following drag preview, a progress spinner that indicates in-flight work, or the playback view of an animation editor are essential under 2.3.3 and stay on. The test is whether removing the motion destroys the information or the function -- if the user can still understand and operate the page without it, it is decorative and must be disableable.

References

  1. [1] W3C (2023). Understanding Success Criterion 2.3.3: Animation from Interactions. W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/animation-from-interactions.html
  2. [2] W3C (2023). Understanding Success Criterion 2.2.2: Pause, Stop, Hide. W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html