Reduced motion
Introduction
Section titled “Introduction”The Reduced motion component provides a toggle for enabling or disabling animations and transitions across your website. It respects the user’s system prefers-reduced-motion preference by default, persists user choices, and exposes a global JavaScript API for programmatic control. This is essential for users with vestibular disorders, motion sensitivity, or those who simply prefer a calmer browsing experience.
When to use
Section titled “When to use”- Accessibility settings panels
- User preference controls
- Sites with significant animations
- WCAG compliance (Success Criterion 2.3.3)
- Command palette / launcher integration
- Supporting users with vestibular disorders
Quick example
Section titled “Quick example”Click the toggle below to switch between normal and reduced motion mode:
Learn how to implement the ReducedMotion component in your project.
---import { ReducedMotion } from 'accessible-astro-components'---
<!-- Default - respects system preference --><ReducedMotion />
<!-- With custom icons --><ReducedMotion> <Icon name="ion:play-outline" slot="off" /> <Icon name="ion:pause-outline" slot="on" /></ReducedMotion>
<!-- Force reduced motion on by default --><ReducedMotion initialMode="on" />
<!-- Force animations on by default (ignores system preference) --><ReducedMotion initialMode="off" />Configure the ReducedMotion component using these available props to customize its behavior and appearance.
| Prop | Type | Default | Description |
|---|---|---|---|
initialMode | 'on' | 'off' | 'auto' | 'auto' | Sets the initial mode. ‘auto’ respects system preference |
label | string | 'Toggle Reduced Motion' | Accessible label for the toggle button |
class | string | '' | Additional CSS classes to apply |
The ReducedMotion component supports named slots for customizing the icons displayed in normal and reduced motion modes.
| Slot | Description |
|---|---|
off | Icon or content to display when animations are enabled |
on | Icon or content to display when reduced motion is active |
JavaScript API
Section titled “JavaScript API”The ReducedMotion component exposes a global window.reducedMotion API for programmatic control. This is useful for integrating with command palettes, launchers, or other UI elements.
// Toggle reduced motion modewindow.reducedMotion.toggle()
// Enable reduced motion (disable animations)window.reducedMotion.enable()
// Disable reduced motion (enable animations)window.reducedMotion.disable()
// Check if reduced motion is enabledwindow.reducedMotion.isEnabled() // returns booleanEvents
Section titled “Events”The component dispatches a reducemotion:change custom event when the mode changes:
document.addEventListener('reducemotion:change', (e) => { console.log('Reduced motion enabled:', e.detail.enabled)})Launcher integration
Section titled “Launcher integration”The component automatically listens for launcher:action events with action: 'toggle-reduced-motion', making it compatible with the Accessible Astro Launcher out of the box.
Accessibility
Section titled “Accessibility”Accessibility isn’t an afterthought - it’s built into the core of this component. The ReducedMotion component is built with accessibility in mind:
- Uses semantic button element
- Proper ARIA attributes (
aria-pressed,aria-label) - Maintains focus states
- Persists across page loads using
localStorage - Respects
prefers-reduced-motionsystem preference by default - Disables all animations and transitions when active
Why reduced motion matters
Section titled “Why reduced motion matters”Some users experience discomfort, dizziness, or nausea when viewing animations. This includes:
- Users with vestibular disorders
- Users with motion sensitivity
- Users with certain cognitive disabilities
- Users who simply prefer less motion
By providing this toggle, you give users control over their browsing experience.
Styling
Section titled “Styling”Make the ReducedMotion component your own with custom styling while maintaining its accessibility features.
Default reduced motion styles
Section titled “Default reduced motion styles”The component includes global styles that disable animations when reduced motion mode is active:
/* These styles are automatically applied */.reduce-motion *,.reduce-motion *::before,.reduce-motion *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important;}Custom animation handling
Section titled “Custom animation handling”You can also check for reduced motion in your own animations:
.animated-element { animation: slide-in 0.3s ease-out;}
/* Disable animation when reduced motion is active */.reduce-motion .animated-element { animation: none;}
/* Or use the media query for CSS-only solutions */@media (prefers-reduced-motion: reduce) { .animated-element { animation: none; }}// Check programmatically before starting animationsif (!window.reducedMotion?.isEnabled()) { element.animate([ { opacity: 0 }, { opacity: 1 } ], { duration: 300, easing: 'ease-out' })}
// Or listen for changesdocument.addEventListener('reducemotion:change', (e) => { if (e.detail.enabled) { // Stop or skip animations cancelAnimationFrame(animationId) }})Interactive examples
Section titled “Interactive examples”See the ReducedMotion component in action with these practical examples.