How to Use prefers-reduced-motion in WordPress Themes
Animations can improve perceived quality, but they can also cause discomfort for some users.
Operating systems provide an accessibility setting called “Reduce Motion”, and browsers expose it via the
CSS media query prefers-reduced-motion.
A WordPress theme should respect this setting by reducing or disabling non-essential motion
while keeping the UI functional.
This is both an accessibility best practice and a practical way to avoid animation-related jank on low-end devices.
What prefers-reduced-motion Does
prefers-reduced-motion can be:
reduce: the user requests less motionno-preference: the user has not requested reduced motion
Your theme should:
- Remove or simplify decorative animations (parallax, long transitions, auto-sliding carousels)
- Keep essential state changes (open/close menus) but make them instant or minimal
- Avoid smooth scrolling when reduce motion is enabled
1) CSS: Disable or Reduce Animations and Transitions
A common baseline is to disable animations and reduce transition duration when motion is reduced.
/* Respect Reduce Motion */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.001ms !important;
scroll-behavior: auto !important;
}
}
This is a “global kill switch”. It’s effective, but may be too aggressive if you rely on specific transitions.
For more control, scope it to your theme components.
2) CSS: Target Only Theme Components (Recommended)
Instead of applying to every element, limit it to your UI parts: menus, accordions, modals, hero animations.
@media (prefers-reduced-motion: reduce) {
.site-header,
.site-nav,
.modal,
.accordion,
.hero {
animation: none !important;
transition: none !important;
}
html:focus-within {
scroll-behavior: auto;
}
}
This keeps third-party widgets or embedded components from being unexpectedly affected.
3) CSS: Replace Motion with Non-Motion Feedback
If you remove animations, you may still want visual affordances.
Use color/opacity changes without movement.
@media (prefers-reduced-motion: reduce) {
.button,
.nav a {
transition: color 0.01ms linear, background-color 0.01ms linear, opacity 0.01ms linear;
}
}
4) JavaScript: Detect Reduced Motion and Disable Animation Logic
If your theme uses JavaScript for animations (IntersectionObserver effects, sliders, GSAP, etc.),
you should also respect the preference in JS.
function wpctPrefersReducedMotion() {
return window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
}
if (wpctPrefersReducedMotion()) {
// Disable or skip non-essential animations.
} else {
// Initialize animations normally.
}
5) JavaScript: Handle Preference Changes Live
Users can change accessibility settings while the page is open (rare, but possible).
You can listen for changes:
var mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
function onMotionPreferenceChange() {
if (mediaQuery.matches) {
// Turn off animation features
} else {
// Turn on animation features
}
}
if (mediaQuery.addEventListener) {
mediaQuery.addEventListener('change', onMotionPreferenceChange);
} else if (mediaQuery.addListener) {
mediaQuery.addListener(onMotionPreferenceChange);
}
This ensures your UI stays consistent with user preferences.
6) WordPress-Friendly Pattern: Add a Body Class
If you want a consistent switch in CSS without repeating media queries,
you can add a body class via a tiny inline script.
This is optional, but useful when you have many components.
Enqueue an Inline Script in WordPress
<?php
add_action( 'wp_enqueue_scripts', function () {
if ( is_admin() ) {
return;
}
// Ensure your main script is enqueued first.
wp_enqueue_script( 'theme-script', get_template_directory_uri() . '/assets/js/main.js', array(), '1.0.0', true );
$inline = <<<JS
(function () {
if (!window.matchMedia) return;
var mq = window.matchMedia('(prefers-reduced-motion: reduce)');
function apply() {
document.documentElement.classList.toggle('reduce-motion', mq.matches);
}
apply();
if (mq.addEventListener) mq.addEventListener('change', apply);
else if (mq.addListener) mq.addListener(apply);
})();
JS;
wp_add_inline_script( 'theme-script', $inline, 'before' );
}, 20 );
Then in CSS:
.reduce-motion .hero,
.reduce-motion .modal {
transition: none !important;
animation: none !important;
}
This can be easier to maintain than repeating media queries everywhere.
7) Common Theme Features to Adapt
Smooth Scrolling
If you enable smooth scrolling globally, disable it for reduced motion:
html {
scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
}
Scroll-Based Reveal Animations
When reduced motion is enabled, render elements “already visible”.
/* Default hidden state for reveal */
.reveal {
opacity: 0;
transform: translateY(16px);
transition: opacity 300ms ease, transform 300ms ease;
}
.reveal.is-visible {
opacity: 1;
transform: none;
}
@media (prefers-reduced-motion: reduce) {
.reveal {
opacity: 1;
transform: none;
transition: none;
}
}
Auto-Playing Sliders
Disable autoplay when reduced motion is enabled, or provide a pause control.
If your slider is custom JS, gate the autoplay:
var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var autoplay = reduce ? false : true;
Testing Checklist
- Enable Reduce Motion in OS settings (macOS/iOS/Windows)
- Test key UI: mobile menu, modal open/close, accordion
- Ensure no “stuck” hidden states (opacity 0, transform offsets)
- Confirm smooth scrolling is disabled under reduce motion
Common Mistakes
- Disabling motion but leaving elements hidden (opacity 0) with no alternative state
- Applying a global kill switch that breaks third-party widgets
- Forgetting JS-driven animations (CSS-only fixes won’t help)
- Keeping autoplay enabled on sliders for reduced-motion users
Summary
prefers-reduced-motionis an accessibility setting that themes should respect- Use CSS media queries to disable non-essential animations and smooth scrolling
- Gate JavaScript animation logic using
matchMedia - Optionally add a
reduce-motionclass for easier maintenance - Always ensure components remain functional with motion removed
By respecting reduced motion, your WordPress theme becomes more accessible, more stable, and often faster—
without giving up modern UI patterns.
🎨 Want to learn more? Visit our WordPress Customization Hub for tips and advanced techniques.