The transition components Collapse, Fade, Grow, Slide, and Zoom (and other MUI components with animations) should have reduced motion in their animations, by either disabling the animations altogether or using a simple fade animation, when the prefers-reduced-motion: reduce media query is true.
None of the components change behaviour and show the same animation when the media query is true.
Here鈥檚 the MDN doc for this media query. It鈥檚 supported on Chrome, Firefox, and Safari on Windows, Mac, and iOS.
This WebKit blog has several examples of how to support this media query.
I鈥檓 currently adding support for this media query in my web app by disabling page transitions and other custom transitions by using the media query in JSS. But I鈥檓 also using MUI鈥檚 built-in transition components and there is currently no easy way to disable those animations.
I could use the useMediaQuery hook to modify what my component returns to remove the transition components, but this is quite cumbersome. Supporting this media query directly would make it a lot easier to build more accessible web apps.
Would the following be an acceptable solution?
import React from 'react';
import useMediaQuery from '@material-ui/core/useMediaQuery';
import { ThemeProvider } from '@material-ui/core/styles';
function App() {
const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)');
const theme = React.useMemo(
() =>
createMuiTheme({
...(prefersReducedMotion
? {
// So we have `transition: none;` everywhere
transitions: { create: () => 'none' },
}
: {}),
}),
[prefersReducedMotion],
);
return (
<ThemeProvider theme={theme}>
<Routes />
</ThemeProvider>
);
}
@oliviertassinari I'm guessing that doesn't affect the transition components? Fade, Grow, etc.
@joshwooding It does disable these components too.
An alternative with global CSS:
@media (prefers-reduced-motion: reduce) {
* {
animation-play-state: paused !important;
transition: none !important;
scroll-behavior: auto !important;
}
}
I'm wondering 馃 I have seen it in https://hankchizljaw.com/wrote/a-modern-css-reset/ (BTW, there are potential good resets we can deploy in CssBasline for v5).
Hey @oliviertassinari, just to confirm: would your solution be something I鈥檇 have to add to each of my React projects using MUI?
@notseenee Regarding your question. Should we have built-in support for the preferred reduced motion preference? Yes, I think that we should explore this path, it sounds better.
@oliviertassinari Yep, I think it鈥檚 in the interest of users and developers to have built-in support for prefers-reduced-motion as opposed to making devs implement it themselves
Suggested here (https://css-tricks.com/revisiting-prefers-reduced-motion-the-reduced-motion-media-query/) to include something along the lines of:
@media screen and
(prefers-reduced-motion: reduce),
(update: slow) {
* {
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.001ms !important;
}
}
Making note that,
Retaining the animation and transition duration also ensures that any functionality that is tied to CSS-based animation will activate successfully (unlike using a declaration of animation: none), while still preventing a disability condition trigger or creating rendering lag
Easy to include at the root of your app:
...
const useStyles = makeStyles(theme => ({
root: {
"@media (prefers-reduced-motion: reduce)": {
"& *": {
animationDuration: "0.001ms !important",
animationIterationCount: "1 !important",
transitionDuration: "0.001ms !important"
}
}
},
}));
....
}
https://codesandbox.io/s/material-ui-prefer-reduced-motion-f1ljg
But I agree having built-in support would be best,
Most helpful comment
Suggested here (https://css-tricks.com/revisiting-prefers-reduced-motion-the-reduced-motion-media-query/) to include something along the lines of:
Making note that,
Easy to include at the root of your app:
https://codesandbox.io/s/material-ui-prefer-reduced-motion-f1ljg
But I agree having built-in support would be best,