Working with reduced motion in Svelte

26th April 2022

Accessibility on the web is important. It’s why frameworks like Svelte have accessibility warnings built in, and why it’s a metric in tools such as lighthouse. You want the ability to control the look and feel of your website for those who use assistive technology, or just want a better experience on the web.

Animations in Svelte are powerful, but for those who prefer reduced motion, some aren’t ideal. A solution to this problem isn’t exactly new. Geoff Rich published a blog post on it back in March 2021. However, I’m lazy and don’t want to implement this on every project. This led me to make svelte-reduced-motion.

I recommend reading this awesome CSS Tricks Article by Eric Bailey. It goes in depth about the benefits people can get from sites that support reduced motion and the prefers-reduced-motion media query.

Getting Started

As per usual, let’s install the dependency.

npm install svelte-reduced-motion -D


To make it easy, we provide a way to use any of Svelte’s built-in transitions out of the box. Later you will learn how you can create custom ones too! By default, all transitions will fall back to fade when reduced motion is requested.

  import { fly } from 'svelte-reduced-motion/transition';

<div transition:fly={{ y: -20 }}>
  I will fly by default, and fade if the user requests reduced motion

All the transitions from svelte/transition are supported with feature parity.

Custom Transitions

With svelte-reduced-motion, it’s easy to set a fallback transition for users who prefer reduced motion. The signature is simple. We can pass in the desired transition and a fallback. We also have a way of customising the options for each individually (the options we pass in the template are passed to both. In some cases, we might need to configure them individually)

  • Simple Example

        import { createTransition } from 'svelte-reduced-motion';
        import { fly } from 'svelte/transition';
        const accessibleTransition = createTransition(fly);
    <!-- You can even specify the options as usual-->
    <div transition:accessibleTransition={{ y: -20 }}>
        Hello world
  • Custom options for each transition

    const accessibleTransition = createTransition(
        [fly, { duration: 1000 }], // default
        [fade, { duration: 200 }]  // reduced-motion fallback
    const accessibleTransition = createTransition(
        [fly, { duration: 750, y: -20 }],

Reacting to reduced motion

The last thing we can do with svelte-reduced-motion is react to whether the user prefers reduced motion. For example, we export a reducedMotion store:

    import { reducedMotion } from 'svelte-reduced-motion';

    Reduced Motion: {$reducedMotion ? 'enabled' : 'disabled'}


Prefers reduced motion is another accessibility item we have to consider in Svelte. CSS provides us with all the tools, and combined with svelte-reduced-motion, we can easily add this consideration to our Svelte projects.