- Как правильно?
- Практическое Применение: определение поведения при прокрутке посредством prefers-reduced-motion
- Учет Предпочтений в анимации В Javascrip
- reduced-motion ещё Не Значит, Что Нет анимаций#
- КОГДА ЛУЧШЕ УДАЛИТЬ АНИМАЦИЮ
- Сумма Всех Частей
- Специальный выключатель движения
- настраиваемые СВОЙСТВА
- ВИДЕО КОМПОНЕНТ
- ИСПОЛЬЗОВАНИЕ ЭЛЕМЕНТА <picture>
- Поддержка Браузеров И Последние Мысли
При работе с анимацией в Интернете важно учитывать, что не все воспринимают её одинаково. То, что может показаться плавным и приятным глазу для одних, может раздражать или отвлекать других — или, что еще хуже, вызывать чувство тошноты или даже вызывать судороги. Веб-сайты с большим количеством анимации также могут оказывать большее влияние на время автономной работы мобильных устройств или приводить к использованию большего количества данных (например, для автоматического воспроизведения видео потребуется больше данных пользователя, чем для статического изображения). Это лишь некоторые из причин, по которым сайты с интенсивным использованием анимации могут быть желательны не для всех.
Большинство новых операционных систем позволяют пользователю настраивать параметры анимации в настройках системного уровня. Медиа-запрос prefers-reduced-motion (параграф спецификации медиа-запросов пятого уровня) позволяет нам определять предпочтения пользователей в отношении анимации на системном уровне и применять стили CSS, которые их учитывают. prefers-reduced-motion может иметь два значения – reduce или no-preference.. Чтобы отключить анимацию элемента, если пользователь явно настроил предпочтение для её уменьшения, мы можем прописать в нашем CSS следующее:
.some-element {
animation: bounce 1200ms;
}
@media (prefers-reduced-motion: reduce) {
.some-element {
animation: none;
}
}
И наоборот, мы можем установить анимацию только в том случае, если у пользователя нет предпочтений в данном аспекте. Это имеет преимущество в том, что сокращает объем кода, который нам нужно написать, и означает, что с меньшей вероятностью мы забудем учесть предпочтения пользователей касаемо анимации:
@media (prefers-reduced-motion: no-preference) {
.some-element {
animation: bounce 1200ms;
}
}
Дополнительным преимуществом является то, что старые браузеры, которые не поддерживают prefers-reduced-motion,- игнорируют это правило и отображают только наш оригинальный элемент без анимации.
Как правильно?
В отличие от медиа-запросов min-width и max-width, где более или менее устоявшиеся соглашения в первую очередь ориентированы на мобильность (поэтому доминирует min-width), не существует единого “правильного” способа написания стилей с уменьшенным количеством анимации. Я склоняюсь ко второму примеру (применение анимации только в том случае, если условие prefers-reduced-motion: no-preference истинно) по причинам, перечисленным выше. Татьяна Мак написала эту превосходную статью, в которой рассматриваются некоторые подходы, которые разработчики могли бы рассмотреть, а также множество других примечательных моментов, включая ключевые вопросы, которые следует задавать при веб-разработке с использованием анимации.
Как всегда, командная коммуникация и последовательная стратегия являются ключом к обеспечению охвата всех аудиторий пользователей, когда речь заходит о комфортном пребывании в Интернете.
Практическое Применение: определение поведения при прокрутке посредством prefers-reduced-motion
prefers-reduced-motion имеет множество приложений, помимо применения (или неприменения) анимации кадров или переходов. Одним из примеров является плавная прокрутка. Если мы установим scroll-behaviour: smooth на нашем html-элементе, когда пользователь нажимает ссылку привязки на странице, она будет плавно прокручиваться до соответствующей позиции на странице (в настоящее время не поддерживается в Safari).:
html {
scroll-behavior: smooth;
}
К сожалению, в CSS у нас сейчас нет особого контроля над этим поведением. Если у нас длинная страница контента, страница прокручивается очень быстро, что может быть довольно неприятным опытом для людей с чувствительностью к резкой анимации. Заключив его в медиа-запрос, мы можем предотвратить применение такого поведения в тех случаях, когда пользователь указал свои предпочтения для снижения уровня анимированности:
@media (prefers-reduced-motion: no-preference) {
html {
scroll-behavior: smooth;
}
}
Учет Предпочтений в анимации В Javascrip
Иногда нам нужно применять движение в JavaScript, а не в CSS. Мы можем аналогичным образом определить предпочтения пользователя в анимации с помощью JS, используя matchMedia. Давайте посмотрим, как мы можем условно реализовать поведение плавной прокрутки в нашем JS-коде:
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)')
button.addEventListener('click', () => {
const behavior = prefersReducedMotion.matches ? 'auto' : 'smooth'
window.scrollTo({
x: 0,
y: 0,
behavior
})
})
Тот же принцип может быть использован для определения того, следует ли реализовывать богатые анимацией интерфейсы пользователей через библиотеки JS - или вообще загружать сами библиотеки.В следующем фрагменте кода функция делает возврат раньше, если пользователь предпочитает уменьшить количество анимации, избегая ненужного импорта большой зависимости — что выигрышно в производительности для пользователя. Если у них нет настроек анимации, мы можем динамически импортировать библиотеку анимации Greensock и инициализировать наши анимации.
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)')
const loadGSAPAndInitAnimations = () => {
if (prefersReducedMotion.matches) return
import('gsap').then((object) => {
const gsap = object.default
/* Initialize animations with GSAP here */
})
}loadGSAPAndInitAnimations()
reduced-motion ещё Не Значит, Что Нет анимаций#
При настройке в стилях минимальной анимации важно, чтобы мы по-прежнему предоставляли пользователю заметные и понятные по смыслу индикаторы произошедших лействий/событий. Например, при отключении отвлекающего или интенсивного подчёркивания наведения для пользователей, которые предпочитают уменьшенную анимацию, мы должны позаботиться о том, чтобы обеспечить четкий альтернативный стиль, когда пользователь наводит курсор на элемент.
Снижение анимации также не обязательно означает удаление всех преобразований и переходов с нашей веб-страницы. Например, кнопка с небольшим значком со стрелкой, которая перемещается на несколько пикселей при наведении, вряд ли вызовет проблемы у тех, кто предпочитает уменьшенную анимацию, и обеспечивает более отчётливую индикацию изменения состояния, чем один только цвет.
Я иногда вижу, как разработчики применяют стили снижения анимации так, что это устраняет все переходы и анимацию на всех элементах:
@media screen and (prefers-reduced-motion: reduce) {
* {
animation: none !important;
transition: none !important;
scroll-behavior: auto !important;
}
}
Это, возможно, лучше, чем игнорировать предпочтения пользователей в движении, но не позволяет нам легко адаптировать элементы для обеспечения более тонких переходов, когда это необходимо.В следующем фрагменте кода у нас есть кнопка, которая увеличивается в масштабе при наведении курсора. Мы меняем цвета и масштаб, но пользователи, предпочитающие уменьшенную анимацию, вообще не получат перехода:
button {
background-color: hotpink;
transition: color 300ms, background-color 300ms, transform 500ms cubic-bezier(.44, .23, .47, 1.27);
}
button:hover,
button:focus {
background-color: darkviolet;
color: white;
transform: scale(1.2);
}
@media screen and (prefers-reduced-motion: reduce) {
* {
animation: none !important;
transition: none !important;
scroll-behavior: auto !important;
}
button {
transition: color 200ms, background-color 200ms;
}
button:hover,
button:focus {
/* Preventing the button scaling on hover */
transform: scale(1);
}
}
Ознакомьтесь с этой демонстрацией, чтобы увидеть эффект. Это, возможно, не идеально, так как внезапное переключение цвета без перехода может вызвать большее раздражение, чем переход в пару сотен миллисекунд. Это одна из причин, по которой в целом я обычно предпочитаю стилизовать анимацию под каждый конкретный случай.
Если вам интересно, это та же демонстрация, переработанная, чтобы при необходимости можно было настроить переход. Она использует настраиваемое свойство для продолжительности перехода, которое позволяет нам включать и выключать изменение масштаба без необходимости переписывать всё объявление стиля.
КОГДА ЛУЧШЕ УДАЛИТЬ АНИМАЦИЮ
Эрик Бейли поднимает вопрос о том, что “не каждое устройство, имеющее доступ к Интернету, может также отображать анимацию или воспроизводить анимацию плавно“ в своей статье “Пересмотр предпочтений - уменьшенная анимация, запрос на мультимедиа с уменьшенной анимацией”. Для устройств с низкой частотой обновления, которые могут вызывать неприятную прерывистую анимацию, на самом деле может быть предпочтительнее удалить анимацию. Медиа-функция update может быть использована для определения таких особенностей:
@media screen and
(prefers-reduced-motion: reduce),
(update: slow) {
* {
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.001ms !important;
}
}
Сумма Всех Частей
При таком внимании к CSS на уровне компонентов важно помнить об общем дизайне страницы. То, что может показаться довольно безобидной анимацией на уровне компонентов, может иметь гораздо большее влияние, если она повторяется на всей странице и является одной из многих движущихся частей.
В статье Татьяны она предлагает организовать анимацию (с prefers-reduced-motion) в одном файле CSS, который может быть загружен только при истинности условия (prefers-reduced-motion: no-preference). Просмотр суммы всех наших анимаций может иметь дополнительное преимущество, помогая нам визуализировать опыт посещения сайта в целом и соответствующим образом адаптировать наши стили с уменьшением анимации.
Специальный выключатель движения
Хотя prefers-reduced-motion это полезно, у него есть недостаток, заключающийся в том, что он обслуживает только пользователей, которые знают об этой функции в своих системных настройках. Многие пользователи не знают об этой настройке, в то время как другие могут использовать заимствованный компьютер без доступа к настройкам на уровне системы. Тем не менее, другие могут быть довольны анимацией на подавляющем большинстве сайтов, но находить сайты с её интенсивным использованием сложными и неприятными для восприятия.
Может быть неудобно изменять настройки системы только для посещения одного сайта. По этим причинам в некоторых случаях может быть предпочтительнее предоставить орган управления на самом сайте для включения и выключения анимации. Мы можем реализовать это с помощью JS.В следующей демонстрации есть несколько кружков, движущихся по фону. Начальные стили анимации определяются системными настройками пользователя (с prefers-reduced-motion), однако пользователь имеет возможность включать или выключать её с помощью кнопки, посредством добавления класса к тегу body, который мы можем использовать для установки стилей в зависимости от выбранного предпочтения. В качестве бонуса выбранные настройки анимации также сохраняются в локальном хранилище - поэтому они «запоминаются» для следующего посещения пользователем.
настраиваемые СВОЙСТВА
Одной из особенностей демонстрации является то, что переключатель устанавливает настраиваемое свойство --playState, которое мы можем использовать для воспроизведения/приостановки анимации. Это может быть особенно удобно, если вам нужно приостановить/воспроизвести несколько анимаций одновременно. Прежде всего, мы устанавливаем состояние воспроизведения на paused:
.circle {
animation-play-state: var(--playState, paused);
}
Если пользователь установил системную настройку уменьшения анимации, мы можем установить состояние воспроизведения на running:
@media (prefers-reduced-motion: no-preference) {
body {
--playState: running;
}
}
Примечание. Установка этого параметра для body, а не для отдельного элемента, означает, что настраиваемое свойство может быть унаследовано.Когда пользователь нажимает переключатель, настраиваемое свойство обновляется для body, что переключает анимацию для любых элементов, в которых оно используется:
// Это приостановит все анимации, которые используют настраиваемое свойство --playState.
document.body.style.setProperty('--playState', 'paused');
Это может быть не идеальное решение во всех случаях, но одно из преимуществ заключается в том, что анимация просто приостанавливается, когда пользователь нажимает переключатель, а не возвращается в исходное состояние, что может быть довольно неприятным.
ВИДЕО КОМПОНЕНТ
В некоторых случаях переключение анимации на уровне компонентов может быть лучшим вариантом. Возьмите веб-страницу с автоматически воспроизводимым видеофоном. Мы должны убедиться, что видео не воспроизводится автоматически для пользователей, предпочитающих ограниченную анимированность, но мы все равно должны предоставить им возможность воспроизводить видео, только если они захотят. Аналогичным образом, если видео настроено на автоматическое воспроизведение для пользователей без заявленных предпочтений, мы также должны предоставить им возможность приостановить видео.
ИСПОЛЬЗОВАНИЕ ЭЛЕМЕНТА <picture>
Крис Койер написал интересную статью, в которой объединил несколько приемов для загрузки медиа из различных источников в зависимости от предпочтений пользователя. Это довольно круто, так как это означает, что для пользователей, которые предпочитают уменьшенную анимацию, гораздо больший файл GIF даже не будет загружен. Обратной стороной, насколько я могу судить, является то, что после загрузки файла у пользователя нет возможности вернуться к альтернативе без движения.
К сожалению, при переключении между опциями наличия/отсутствия анимации в Chrome кажется, что файл GIF загружается заново каждый раз, чего нет в других браузерах.
Тем не менее, этот метод кажется более безопасным способом отображения GIF-файлов, которые могут быть источником неприятных ощущений для пользователей.
Поддержка Браузеров И Последние Мысли
prefers-reduced-motion уже пару лет имеет отличную поддержку во всех современных браузерах. Как мы видели, при использовании подхода с ограниченной анимацией не поддерживающие браузеры просто игнорируют его. Нет причин не использовать его сегодня, чтобы сделать ваши сайты более удобными.
У настраиваемых переключателей определенно есть место, и они могут значительно улучшить опыт пользователей, которые не знают об этом параметре или о том, что он делает. Обратной стороной для пользователя является непоследовательность: если каждый разработчик вынужден предлагать собственное решение, пользователю нужно искать выключатель анимации в разных местах на каждом веб-сайте.
Похоже, что здесь недостающий слой - это браузеры. Мне бы хотелось, чтобы браузеры реализовали переключатели анимации где-нибудь в легкодоступном для пользователя месте, чтобы люди знали, где их найти, независимо от того, какой сайт они просматривают. Это может побудить разработчиков уделять больше времени обеспечению доступности настроек анимации.