Запрос prefers-reduced-motion media определяет, запрашивал ли пользователь у операционной системы минимизацию количества используемой анимации или движения.
Не всем нравятся декоративные анимации или переходы, а некоторые пользователи испытывают настоящую укачивание при использовании параллаксной прокрутки, эффектов масштабирования и тому подобного. Запрос медиаданных для пользовательских предпочтений prefers-reduced-motion позволяет создать вариант вашего сайта с уменьшенным количеством анимации для пользователей, выразивших такое предпочтение.
Слишком много движения в реальной жизни и в интернете.
На днях я каталась на коньках с детьми. День был чудесный, светило солнце, и каток был битком набит людьми ⛸. Единственная проблема: я плохо переношу толпы. Когда вокруг столько движущихся объектов, я не могу ни на чём сосредоточиться, теряюсь в догадках и испытываю чувство полной визуальной перегрузки, почти как если бы смотрела на муравейник 🐜.

Occasionally, the same can happen on the web: with flashing ads, fancy parallax effects, surprising reveal animations, autoplaying videos, and more, the web sometimes can be quite overwhelming … Happily, unlike in real life, there is a solution to that. The CSS media query prefers-reduced-motion lets developers create a variant of a page for users who, well, prefer reduced motion. This can consist of anything from refraining from having autoplaying videos to disabling certain purely decorative effects, to completely redesigning a page for certain users.
Прежде чем я углублюсь в описание этой функции, давайте немного отступим назад и подумаем, для чего используется анимация в веб-разработке. При желании вы можете пропустить вводную информацию и сразу перейти к техническим деталям .
Анимация в интернете
Анимация часто используется для предоставления пользователю обратной связи , например, чтобы сообщить ему о получении и обработке действия. Например, на сайте интернет-магазина товар может быть анимирован таким образом, чтобы он «влетел» в виртуальную корзину, изображенную в виде значка в правом верхнем углу сайта.
Другой вариант использования предполагает применение анимации для манипулирования восприятием пользователя путем сочетания скелетных экранов, контекстных метаданных и низкокачественных предварительных просмотров изображений, чтобы занять много времени пользователя и ускорить весь процесс. Идея состоит в том, чтобы дать пользователю контекст того, что его ждет, и одновременно максимально быстро загрузить все необходимые элементы.
Finally, there are decorative effects like animated gradients, parallax scrolling, background videos, and several others. While many users enjoy such animations, some users dislike them because they feel distracted or slowed down by them. In the worst case, users may even suffer from motion sickness as if it were a real life experience, so for these users reducing animations is a medical necessity .
Вестибулярное расстройство спектра, вызванное движением
Some users experience distraction or nausea from animated content . For example, scrolling animations can cause vestibular disorders when elements other than the main element associated with the scrolling move around a lot. For example, parallax scrolling animations can cause vestibular disorders because background elements move at a different rate than foreground elements. Vestibular (inner ear) disorder reactions include dizziness, nausea, and migraine headaches, and sometimes require bed rest to recover.
Удаление движения в операционных системах
Many operating systems have had accessibility settings for specifying a preference for reduced motion for a long time. The following screenshots show macOS Mojave's Reduce motion preference and Android Pie's Remove animations preference. When checked, these preferences cause the operating system to not use decorative effects like app launching animations. Applications themselves can and should honor this setting, too, and remove all unnecessary animations.


Удалить движение в интернете
Media Queries Level 5 brings the reduced motion user preference to the web as well. Media queries allow authors to test and query values or features of the user agent or display device independent of the document being rendered. The media query prefers-reduced-motion is used to detect if the user has set an operating system preference to minimize the amount of animation or motion it uses. It can take two possible values:
-
no-preference: Указывает, что пользователь не указал никаких предпочтений в отношении используемой операционной системы. В логическом контексте значение этого ключевого слова оценивается какfalse. -
reduce: Указывает, что пользователь установил в настройках операционной системы параметр, согласно которому интерфейс должен минимизировать движение или анимацию, предпочтительно до тех пор, пока не будет удалено все несущественные движения.
Работа с медиазапросами в контексте CSS и JavaScript.
Как и в случае со всеми медиа-запросами, prefers-reduced-motion можно проверить как в контексте CSS, так и в контексте JavaScript.
To illustrate both, assume I have an important sign-up button that I want the user to click. I could define an attention-catching "vibrate" animation, but as a good web citizen I will only play it for those users who are explicitly OK with animations, but not everyone else, which can be users who have opted out of animations, or users on browsers that don't understand the media query.
/*
If the user has expressed their preference for
reduced motion, then don't use animations on buttons.
*/
@media (prefers-reduced-motion: reduce) {
button {
animation: none;
}
}
/*
If the browser understands the media query and the user
explicitly hasn't set a preference, then use animations on buttons.
*/
@media (prefers-reduced-motion: no-preference) {
button {
/* `vibrate` keyframes are defined elsewhere */
animation: vibrate 0.3s linear infinite both;
}
}
To illustrate how to work with prefers-reduced-motion with JavaScript, imagine I have defined a complex animation with the Web Animations API . While CSS rules will be dynamically triggered by the browser when the user preference changes, for JavaScript animations I have to listen for changes myself, and then manually stop my potentially in-flight animations (or restart them if the user lets me):
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
mediaQuery.addEventListener('change', () => {
console.log(mediaQuery.media, mediaQuery.matches);
// Stop JavaScript-based animations.
});
Обратите внимание, что скобки вокруг самого медиа-запроса обязательны:
window.matchMedia('prefers-reduced-motion: reduce');
window.matchMedia('(prefers-reduced-motion: reduce)');
Работа с медиа-запросами из контекста <picture>
Интересный вариант использования — сделать воспроизведение анимированных AVIF-, WebP- или GIF-файлов зависимым от атрибута media . Если (prefers-reduced-motion: no-preference) возвращает true , то можно безопасно отображать анимированную версию, в противном случае — статическую:
<picture>
<!-- Animated versions. -->
<source
srcset="nyancat.avifs"
type="image/avif"
media="(prefers-reduced-motion: no-preference)"
/>
<source
srcset="nyancat.gif"
type="image/gif"
media="(prefers-reduced-motion: no-preference)"
/>
<!-- Static versions. -->
<img src="nyancat.png" alt="Nyan cat" width="250" height="250" />
</picture>
Вы можете увидеть следующий пример. Попробуйте изменить настройки движения на вашем устройстве, чтобы увидеть разницу.

Узнайте предпочтения пользователя во время запроса.
Заголовок клиентской подсказки Sec-CH-Prefers-Reduced-Motion позволяет сайтам получать предпочтения пользователя относительно анимации во время запроса, что дает серверам возможность встраивать соответствующие CSS-стили для повышения производительности.
Демо
I have created a little demo based on Rogério Vicente's amazing 🐈 HTTP status cats . First, take a moment to appreciate the joke, it's hilarious and I'll wait. Now that you're back, let me introduce the demo . When you scroll, each HTTP status cat alternatingly appears from either the right or the left side. It's a buttery smooth 60 FPS animation, but as outlined before, some users may dislike it or even get motion sick by it, so the demo is programmed to respect prefers-reduced-motion . This even works dynamically, so users can change their preference on-the-fly, no reload required. If a user prefers reduced motion, the non-necessary reveal animations are gone, and just the regular scrolling motion is left. The following screencast shows the demo in action:
prefers-reduced-motionВыводы
Уважение к предпочтениям пользователей — ключевой аспект современных веб-сайтов, и браузеры предоставляют всё больше функций, позволяющих веб-разработчикам это делать. Ещё один пример — prefers-color-scheme , который определяет, предпочитает ли пользователь светлую или тёмную цветовую схему. Подробнее о prefers-color-scheme вы можете прочитать в моей статье «Привет, тьма, мой старый друг 🌒».
Рабочая группа CSS стандартизирует больше медиа-запросов, определяющих предпочтения пользователей, таких как prefers-reduced-transparency (определяет, предпочитает ли пользователь уменьшенную прозрачность), prefers-contrast (определяет, запросил ли пользователь у системы увеличение или уменьшение контраста между соседними цветами) и inverted-colors (определяет, предпочитает ли пользователь инвертированные цвета).
(Бонус) Принудительное ограничение анимации на всех сайтах
Не каждый сайт будет использовать prefers-reduced-motion , или, возможно, не в достаточной степени, чтобы удовлетворить ваши предпочтения. Если по какой-либо причине вы хотите остановить анимацию на всех веб-сайтах, вы можете это сделать. Один из способов — внедрить таблицу стилей со следующим CSS-кодом на каждую посещаемую вами веб-страницу. Существует несколько расширений для браузеров (используйте на свой страх и риск!), которые позволяют это сделать.
@media (prefers-reduced-motion: reduce) {
*,
::before,
::after {
animation-delay: -1ms !important;
animation-duration: 1ms !important;
animation-iteration-count: 1 !important;
background-attachment: initial !important;
scroll-behavior: auto !important;
transition-duration: 1ms !important;
transition-delay: -1ms !important;
}
}
The way this works is that the previous CSS overrides the durations of all animations and transitions to such a short time that they are not noticeable anymore. As some websites depend on an animation to be run in order to work correctly (maybe because a certain step depends on the firing of the animationend event ), the more radical animation: none !important; approach wouldn't work. Even the previous hack is not guaranteed to succeed on all websites (for example, it can't stop motion that was initiated using the Web Animations API ), so be sure to deactivate it when you notice breakage.
Ресурсы
- Последний вариант спецификации «Запросы в СМИ» 5-го уровня, подготовленный редактором.
-
prefers-reduced-motionon Chrome Platform Status . - Ошибка Chromium в функции
prefers-reduced-motion. - Blink Intent to Implement posting .
Благодарности
Огромная благодарность Стивену МакГруэру , который реализовал prefers-reduced-motion в Chrome и вместе с Робом Додсоном также проверил этот документ.