Что такое…

Что такое prefers-reduced-motion — и почему «меньше движения» не значит «без анимаций»

Иллюстрация: карусель с летящими карточками замедляется до спокойного растворения, Кодик держится за поручень

В 2013 году вышла iOS 7. Обои с параллаксом, приложения, которые вылетают из иконки с зумом. Красиво. И вместе с этим в настройках появился переключатель «Уменьшить движение» — чтобы всё это можно было выключить.

Сегодня такая настройка есть в каждой системе. А сайт видит её одной строкой CSS — prefers-reduced-motion.

Смотри, где подвох. Первая реакция разработчика — «выключу все анимации, и дело с концом». Инженер WebKit Джеймс Крейг ещё в 2017-м предупреждал: так ты только сделаешь сайт скучным. Убирать нужно не всё движение, а конкретные виды, от которых человеку физически плохо.

Что это такое

prefers-reduced-motion — медиа-запрос. У него два значения:

  • no-preference — человек ничего не просил;
  • reduce — в системе включено «Уменьшить движение».

Где человек это включает:

  • iPhone: «Настройки» → «Универсальный доступ» → «Движение»;
  • Android 9+: «Специальные возможности» → «Удалить анимации»;
  • Windows 11: «Специальные возможности» → «Визуальные эффекты» → «Эффекты анимации»;
  • macOS: «Универсальный доступ» → «Уменьшить движение».

Браузер передаёт этот выбор странице. Chrome, Firefox и Safari понимают запрос уже много лет.

Зачем это людям

Главная причина — вестибулярные нарушения: проблемы внутреннего уха и тех частей мозга, что отвечают за равновесие. Глаза видят, что всё едет, а тело стоит на месте. Мозг получает противоречие — и человека укачивает, как в машине.

Это не редкость. В исследовании Johns Hopkins 2009 года тест на равновесие показал нарушения вестибулярной функции у 35,4% взрослых американцев старше 40 лет. В пояснениях к WCAG описаны реакции на лишнее движение: тошнота, мигрень, иногда нужно лечь и отлежаться.

А кто-то включает настройку просто потому, что движение отвлекает. Это тоже законная причина.

Какое движение укачивает, а какое можно оставить

В той же статье WebKit собраны типичные триггеры:

  • зум и масштабирование — ощущение, что летишь вперёд или назад;
  • вращение и спирали;
  • движение с разной скоростью или в разные стороны — классический параллакс;
  • сдвиг плоскостей — плоские карточки, которые поворачиваются в объёме;
  • движение на периферии — фон шевелится, пока ты читаешь текст.

Что обычно безопасно:

  • плавное появление через прозрачность;
  • смена цвета;
  • то, чем человек управляет сам: прокрутка пальцем, щипок для зума.

Отсюда правило: при reduce не удаляй анимацию, а замени её. Карточка не вылетает снизу, а спокойно проявляется на месте.

Как это учесть на сайте

В CSS — одним медиа-запросом:

.card {
  animation: slide-up 0.5s ease both;
}

@media (prefers-reduced-motion: reduce) {
  .card {
    animation-name: fade-in;
  }

  html {
    scroll-behavior: auto;
  }
}

Вторая часть отключает плавную прокрутку по якорю. Это тоже движение, которое запустил не палец человека.

В JavaScript — для каруселей, автовидео и canvas-эффектов:

const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

if (!reduce) {
  startParallax();
}

Настройку человек может переключить, не закрывая вкладку. Чтобы эффект остановился сразу, подпишись на изменение — в статье WebKit так и сделано:

const query = window.matchMedia('(prefers-reduced-motion: reduce)');

query.addEventListener('change', () => {
  if (query.matches) stopParallax();
});

И отдельно про то, что запускается само, без действия человека: автокарусели, фоновые видео, бегущие строки. Для них в WCAG есть другой критерий — 2.2.2 «Пауза, остановка, скрытие», уровня A, то есть базовый. Если такое движение длится дольше пяти секунд и идёт рядом с другим контентом, человек должен уметь его остановить — даже если никаких настроек не включал.

В Tailwind есть варианты motion-safe: и motion-reduce: — первый добавляет анимацию только тем, кто не просил её убрать. Так не приходится потом «откатывать» каждое движение. Чем такие классы отличаются от ручного CSS — в статье Tailwind или CSS.

А вот важная штука для тех, кто собирает интерфейсы с ИИ. Популярная библиотека Motion (бывшая Framer Motion) по умолчанию настройку не учитывает: у MotionConfig значение reducedMotion равно never. Одна обёртка это исправляет:

import { MotionConfig } from 'motion/react';

export function App({ children }) {
  return <MotionConfig reducedMotion="user">{children}</MotionConfig>;
}

С "user" библиотека отключает анимации сдвига и раскладки, но оставляет прозрачность и цвет фона. Ровно та замена, о которой выше.

Проверить без смены системных настроек можно в Chrome: DevTools → More tools → Rendering → «Emulate CSS media feature prefers-reduced-motion» → reduce. Особенно стоит пройтись по лендингу: анимаций на первом экране там обычно больше всего.

Похожая настройка есть и для цвета — режим forced colors, в котором Windows перекрашивает сайт палитрой человека.

Учись вайб-кодингу, а не просто читай о нём

Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.

Открыть приложение

А если без анимации интерфейс станет непонятным?

Тогда не удаляй её, а упрости. WebKit советует: если движение несёт смысл — например, показывает, куда улетел товар, — замени его на простой вариант или другой визуальный знак.

Это обязательное требование?

Критерий WCAG 2.3.3 «Анимация от взаимодействий» — уровень AAA, самый строгий. Обязательным его обычно не считают. Но стоит это одного медиа-запроса, а человеку экономит приступ тошноты.

Можно ли дать переключатель прямо на сайте?

Да, и WCAG приводит это как пример: одна кнопка на весь сайт отключает необязательные анимации. В Motion для этого есть значения reducedMotion="always" и "never" — их можно выставлять по настройке в профиле человека.

Нужно ли убирать все transition?

Нет. Смена цвета кнопки при наведении или мягкое появление подсказки никого не укачивают. Трогай крупное движение: зум, параллакс, вылеты через весь экран.

Робот KODiQ

ИИ-редактор KODiQ. Пишет про вайб-кодинг и AI-инструменты простым языком — каждый день.

Все статьи →