Canonical: https://motionspec.dev/blog/elementor-animations-reduced-motion

Guide

# Elementor and prefers-reduced-motion: what the plugin covers

[Kevin Fröba](https://motionspec.dev/about) · 2026-10-09 · MotionSpec

**Elementor answers the reduced-motion setting for most of its motion: since version 3.32, entrance animations and CSS transitions stand down when a visitor has asked their system to reduce motion, and its slider code turns carousel autoplay off for the same visitors. Three things stay open: hover effects built on keyframes keep looping, background video ignores the setting, and visitors without the setting get no way to stop a carousel.** This guide maps what Elementor's own code does, read from its source on GitHub, and closes the gaps with one CSS rule, two settings and a short browser test.

## What does Elementor do when Reduce Motion is on?

**It switches off entrance animations and sets every CSS transition to zero.** The [Elementor changelog](https://github.com/elementor/elementor/blob/main/changelog.txt) for version 3.32.0 (2025-09-15) lists the fix: "Reduced-motion preferences are not applied to entrance and exit animations". In the [stylesheet source on Elementor's main branch](https://github.com/elementor/elementor/blob/main/assets/dev/scss/frontend/_animate.scss) (package version 4.4.0, read on 2026-10-09) the rule that does the work is short:

```css
@media (prefers-reduced-motion: reduce) {
  .animated {
    animation: none !important;
  }
  html * {
    transition-duration: 0s !important;
    transition-delay: 0s !important;
  }
}
```

Every entrance animation is a class pair on the element — `animated` plus the effect, such as `fadeInUp` — so the first block switches them all off. The second block zeroes every CSS transition on the page. That covers the transition-based hover effects — Grow, Shrink, Bounce In and Out, Rotate, Grow Rotate, Float, Sink and the three Skews — and anything else on the page that eases between two states. Version 3.25.0 had already made Elementor's smooth scrolling respect the same preference.

Carousels and background slideshows go through Elementor's own [Swiper wrapper](https://github.com/elementor/elementor/blob/main/assets/dev/js/frontend/utils/swiper.js). In the current source it checks the same media query and, when it matches, creates the slider with `speed: 0` and `autoplay: false`. The slow Ken Burns zoom on background slideshows is a CSS transition, so the `html *` rule above flattens it as well.

## Which Elementor animations keep running?

**Hover effects that use keyframes.** Elementor's Pulse hover effect is defined in its own [small stylesheet](https://github.com/elementor/elementor/blob/main/assets/lib/animations/styles/e-animation-pulse.css):

```css
.elementor-animation-pulse:active,
.elementor-animation-pulse:focus,
.elementor-animation-pulse:hover {
  animation-name: elementor-animation-pulse;
  animation-duration: 1s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
```

The element carries no `animated` class, so the reduced-motion rule never reaches it. We loaded Elementor's stylesheets in Chromium with Reduce Motion on: the entrance animation resolved to `none`, the Grow transition to `0s`, and the hovered Pulse button kept running `elementor-animation-pulse`, infinitely, for as long as it was hovered or focused. The other keyframe hover effects in the same library — Pulse Grow, Pulse Shrink, Push, Pop, Bob, Hang, the seven Wobbles, Buzz and Buzz Out — are built the same way.

That is a gap in the [WCAG 2.3.3](https://motionspec.dev/blog/wcag-2-3-3-animation-from-interactions) lane, Animation from Interactions (Level AAA): the visitor's own hover starts the motion, so it is a best-practice gap rather than a Level A failure. It is also easy to close. Add one rule wherever the site keeps its custom CSS, for example the child theme's stylesheet:

```css
@media (prefers-reduced-motion: reduce) {
  [class*="elementor-animation-"] {
    animation: none !important;
  }
}
```

With it in place, the same Chromium check reports `none` for the hovered Pulse button. Every keyframe hover effect uses an `elementor-animation-` class, so the one selector reaches all of them; the transition-based effects already stop under Elementor's own rule.

## What does Elementor leave to you?

**A way to stop what starts by itself.** Everything above answers the visitor's system setting — the 2.3.3 rail, which only reaches people who have found that setting. [WCAG 2.2.2](https://motionspec.dev/blog/wcag-2-2-2-pause-stop-hide) (Level A) asks for a control that any visitor can use on the page, and three Elementor features start motion without one:

- **Carousel autoplay.** The carousel widgets run on Swiper. For visitors without the reduced-motion setting, the [carousel handler](https://github.com/elementor/elementor/blob/main/assets/dev/js/frontend/handlers/base-carousel.js) follows the widget's Autoplay setting; Pause on Hover calls Swiper's `stop()` when the pointer enters and `start()` when it leaves, and keyboard focus inside the carousel stops it. There is no visible stop button. Switch Autoplay off, or add a button — the pattern is in [the Swiper and Splide pause-button guide](https://motionspec.dev/blog/swiper-splide-autoplay-pause-button). The handler exposes each carousel's Swiper instance as jQuery data named `swiper` on the carousel container, which is where such a button can reach it.
- **Background slideshow.** A background can rotate its images with Swiper autoplay and a slow Ken Burns zoom on each slide. For visitors without the setting, the same answer applies: a control, or no autoplay.
- **Background video.** A self-hosted background video is rendered with `autoplay muted playsinline` and, unless Play Once is set, `loop`; there are no controls, and the video handler has no reduced-motion check, so it plays for visitors who asked for reduced motion too. Play Once ends the loop — and for a self-hosted file the handler hides the video when it ends — which takes a clip of five seconds or less out of 2.2.2's scope. A longer clip still needs a pause control; see [background video and WCAG 2.2.2](https://motionspec.dev/blog/background-video-wcag-2-2-2).

## How do you test an Elementor page?

1. Turn on your operating system's reduce-motion setting, or emulate it in Chrome DevTools — the four ways are in [prefers-reduced-motion, explained](https://motionspec.dev/blog/prefers-reduced-motion).
2. Reload and scroll. Elements with entrance animations should appear in place, without sliding, fading or zooming in, and carousels and background slideshows should stand still.
3. Hover over, and Tab through, buttons, icons and image boxes. Anything that still pulses, bobs, hangs or buzzes is a keyframe hover effect without the rule above.
4. With the setting still on, look at every background video. If it plays, it needs the reduced-motion start from the background video guide.
5. Turn the setting off again, reload, and watch every carousel, background slideshow and background video for ten seconds without touching anything. Anything still moving needs a control you can reach with Tab.
6. Run [the free motion check](https://motionspec.dev/motion-check) on the URL for the CSS side — and read the next section before acting on its list.

## How do you read the free check on an Elementor site?

**Treat entrance animations it lists as "check in the browser", not as failures.** Our check matches a reduced-motion guard to a motion rule by selector. Elementor guards on `.animated` and animates on `.fadeInUp`, so on a test page with Elementor's stylesheet and the fadeInUp file, the engine reported `.fadeInUp` as motion without a reduced-motion guard — although in a browser, where the element carries both classes, that animation resolves to `none`. The keyframe hover effects, by contrast, are correctly listed as unguarded. On Pulse the engine also raises a WCAG 2.2.2 candidate for the infinite loop; on a hover effect that is a judgement call, because the motion starts with the visitor's hover rather than automatically. Carousel autoplay shows up at most as a note that a runtime motion library was detected and not audited, when the page loads Swiper's script. Background video does not appear at all.

## What this does not cover

- **Elementor Pro's Motion Effects.** The scrolling and mouse effects in Pro are not in the public repository, so we could not read them. Test them with steps 1 to 4 above.
- **Versions before 3.32.** There, entrance animations ignore the preference. Update, or add `.animated { animation: none!important; }` inside a `prefers-reduced-motion: reduce` media query yourself.
- **Add-on packs and themes.** Third-party widget packs ship their own CSS and JavaScript, outside Elementor's rule. The browser test above finds them; the code reading here does not.
- **Content that waits for a script.** Elementor hides elements that have an entrance animation (`.elementor-invisible { visibility: hidden; }`) until its script reveals them as they scroll into view, with Reduce Motion on as well. That is not motion, but it is content that depends on JavaScript to be seen.

**Scope note: this is detection, not a conformance verdict.**

The [free CSS animation accessibility checker](https://motionspec.dev/motion-check) reads a page's linked CSS files and inline style blocks and reports the failing patterns it can see, each with a fix. It does not certify a page, and it is not a legal determination. For the full manual process across a page's motion — criteria, patterns and checks in order — see [how to verify web motion accessibility](https://motionspec.dev/blog/verify-web-motion-accessibility).

## FAQ

### Does Elementor respect prefers-reduced-motion?

Partly. Since version 3.32.0, Elementor’s stylesheet switches off entrance animations and sets every CSS transition to zero seconds when the visitor has asked for reduced motion, and in the current source its Swiper wrapper also turns carousel and slideshow autoplay off for those visitors. Hover effects built on keyframes, such as Pulse, keep running, and a background video still plays.

### How do I stop Elementor hover animations for users who prefer reduced motion?

Add a prefers-reduced-motion: reduce media query that sets animation: none!important on every element whose class contains elementor-animation-. The keyframe hover effects all use such a class, so one rule reaches all of them. Transition-based effects such as Grow are already stopped by Elementor’s own rule.

### Is an Elementor carousel with autoplay a WCAG 2.2.2 issue?

It is in scope for every visitor who has not set a reduced-motion preference: the rotation starts automatically, continues past five seconds and sits alongside other content. Elementor’s carousel widgets pause while hovered and stop when keyboard focus moves inside, but they have no visible button to stop the rotation. Turning Autoplay off takes the widget out of scope; keeping it means adding a stop control.

[Seen in the wild: what we measured on 50 real WordPress sites →](https://motionspec.dev/wordpress-motion-accessibility)

MotionSpec checks and compiles UI animation for AI-generated web apps — it does not generate AI video.
