Svelte: Built-in support for respecting the `prefers-reduced-motion` flag with animations/transitions

Created on 2 Sep 2020  路  3Comments  路  Source: sveltejs/svelte

Is your feature request related to a problem? Please describe.
I was thinking about new ways to honor a user's request to have a less frustrating experience with animations and eventually wondered if this flag is something Svelte itself could (whether as default on or default off) "respect."

Describe the solution you'd like
If Svelte respected prefers-reduced-motion out of the box, it could opt-out of any transitions or animations automatically without extra effort on the developer's part. Alternatively, this could be a flag to the various animation features that signal whether they should skip an animation instruction if prefers-reduced-motion is on.

Describe alternatives you've considered
I've done this in the past manually (in three.js/WebGL land) so I think it's certainly doable by the developer if left to their own devices, and can be done today in Svelte without formal support from the library.

How important is this feature to you?
I've always appreciated how Svelte helps developers do the right thing, and tries to lessen the pain of the "right thing" if you were left to coding it yourself. If a user is making the request to not have gratuitous or potentially harmful animations, I believe we should do whatever we can to respect that. In my opinion, this feels like a prime candidate for Svelte to encourage and enable the humane choice of respecting the user's request.

animations transitions proposal

Most helpful comment

svelte/motion is an extension of svelte/store, if you know for sure that setting your values instantly won't break your uses of spring and tweened, the apis are so similar you'll most likely be fine just re-exporting them as writables

import { spring as svelte_spring, tweened as svelte_tweened } from "svelte/motion";
import { writable } from "svelte/store";

const reduce_motion = matchMedia("(prefers-reduced-motion: reduce)").matches;

export const spring = reduce_motion ? writable : svelte_spring;
export const tweened = reduce_motion ? writable : svelte_tweened;

That's honestly as far as you'll get in terms of support for that feature given the constrains set by the v3 design

All 3 comments

All animations/transitions in svelte are done through pure css, simply add the following to your global style sheet

@media (prefers-reduced-motion: reduce) {
  * {
    animation-delay: 0ms !important;
    animation-duration: 1ms !important;
  }
}

All animations/transitions in svelte are not done through pure css.

Tweening is VERY much not done though css. The entire motion package isn't CSS

svelte/motion is an extension of svelte/store, if you know for sure that setting your values instantly won't break your uses of spring and tweened, the apis are so similar you'll most likely be fine just re-exporting them as writables

import { spring as svelte_spring, tweened as svelte_tweened } from "svelte/motion";
import { writable } from "svelte/store";

const reduce_motion = matchMedia("(prefers-reduced-motion: reduce)").matches;

export const spring = reduce_motion ? writable : svelte_spring;
export const tweened = reduce_motion ? writable : svelte_tweened;

That's honestly as far as you'll get in terms of support for that feature given the constrains set by the v3 design

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bestguy picture bestguy  路  3Comments

thoughtspile picture thoughtspile  路  3Comments

1u0n picture 1u0n  路  3Comments

Rich-Harris picture Rich-Harris  路  3Comments

clitetailor picture clitetailor  路  3Comments