Что разберём
1Что анимируем, а что нет
Правила начинаются не с чисел, а со списка изменений, которые бывают в продукте, и решения по каждому.
Анимируют не элементы, а изменения.
Шторка — это «крупный элемент появляется поверх экрана», строка корзины — «элемент уходит из списка».
Изменений в продукте немного, и для каждого решение принимается один раз:
| Изменение | Движение | Токены | При «уменьшить движение» |
|---|---|---|---|
| Отклик на нажатие: кнопка, строка | Нет, только цвет | быстро | Без изменений |
| Мелкое изменение на месте: переключатель, флажок, число | На месте | быстро · перемещение | Сразу, без сдвига |
| Небольшой элемент поверх: меню, подсказка, плашка | Вырастает от источника | коротко · появление; уход — коротко · уход | Проявление |
| Крупный элемент поверх: шторка, диалог | От края или из центра | средне · появление; уход — коротко · уход | Проявление |
| Элемент уходит из списка | Уходит, соседи смыкаются | коротко · уход, затем коротко · перемещение | Сразу, без сдвига |
| Смена экрана вперёд и назад | По направлению перехода | долго · перемещение | Растворение |
| Загрузка | Индикатор или каркас экрана | равномерно | Индикатор остаётся |
| Данные обновились сами: статус заказа | Новое значение проявляется | коротко · появление | Сразу |
| Украшение: промо, первый заказ, пустой экран | Один раз, не в рабочих сценариях | по месту, до секунды | Не показывать |
| Автоматическое: баннеры, видео | Только по нажатию | — | — |
Токены в таблице — набор из урока Middle: длительности «быстро» 100 мс, «коротко» 200, «средне» 300, «долго» 400 и кривые «появление», «уход», «перемещение».
2Длительности и кривые в токенах
Числа движения живут в одном месте, одинаково в макете и в коде, и называются по роли.
Устройство то же, что у цвета: два слоя.
- Базовые значения — числа с порядковыми именами;
- роли — имена, которыми пользуются компоненты.
Компонент берёт роль, а не число. Когда меняется значение, правка идёт в одном месте.
:root {
/* базовые значения: только внутри системы */
--duration-100: 100ms;
--duration-200: 200ms;
--duration-300: 300ms;
--duration-400: 400ms;
/* роли: ими пользуются компоненты */
--duration-fast: var(--duration-100);
--duration-short: var(--duration-200);
--duration-medium: var(--duration-300);
--duration-long: var(--duration-400);
--ease-enter: cubic-bezier(0, 0, 0, 1);
--ease-exit: cubic-bezier(0.3, 0, 1, 1);
--ease-move: cubic-bezier(0.2, 0, 0, 1);
}
/* компонент берёт роли, а не числа */
.sheet {
transition: transform var(--duration-medium) var(--ease-enter);
}
.sheet.is-closing {
transition: transform var(--duration-short) var(--ease-exit);
}
Формат для обмена
Для обмена между макетом и кодом есть формат дизайн-токенов, который выпустила группа сообщества при W3C.
Стандартом W3C он не считается, но Figma и инструменты разработки его уже понимают. В нём у длительности и у кривой свои типы:
{
"duration": {
"short": { "$type": "duration", "$value": { "value": 200, "unit": "ms" } },
"medium": { "$type": "duration", "$value": { "value": 300, "unit": "ms" } }
},
"ease": {
"enter": { "$type": "cubicBezier", "$value": [0, 0, 0, 1] },
"exit": { "$type": "cubicBezier", "$value": [0.3, 0, 1, 1] }
}
}
В макете
Роли становятся переменными библиотеки или хотя бы страницей с таблицей, на которую ссылается каждый прототип.
Прототип, где длительность вписана руками, при ревью отправляется назад так же, как цвет не из палитры.
Правила движения этого сайта, для примера, умещаются в три значения. Это 150 мс для смены цвета при наведении, 200 мс для шторки фильтров и одна кривая cubic-bezier(0.2, 0, 0, 1). Все три — токены в одном файле темы. При «уменьшить движение» переходы сокращаются почти до нуля: ни один из них не несёт смысла, который без движения потеряется.
3«Добавим, чтобы было живее»
На просьбу добавить движение отвечают не вкусом, а тремя вопросами.
- Что оно объясняет? Какое изменение станет понятнее. «Будет живее» — не изменение.
- Как часто его увидят? Раз в жизни, раз в день или сорок раз за визит.
- Сколько оно стоит? Время человека, плавность на слабом телефоне, люди с настройкой «уменьшить движение».
Ответ бывает не только «да» и «нет». Нередко просьба разумная, а параметры надо привести к правилам.
Проверьте себя
Восемь просьб от команды. Что ответить на каждую?
«Пусть логотип на заставке крутится две секунды, это наш бренд».
ОтклонитьНичего не объясняет, а видят при каждом запуске: каждое открытие начинается с двух секунд ожидания. Бренду место в промо и в первом запуске.
«Шторка фильтров пусть выезжает снизу, а не появляется разом».
ПринятьЭто строка «крупный элемент поверх»: средне · появление, уход — коротко · уход, при «уменьшить движение» — проявление.
«Кнопка „Оформить“ пусть пульсирует, чтобы на неё чаще нажимали».
ОтклонитьДвижение без изменения. Оно отвлекает от чтения, а бесконечное движение к тому же надо уметь остановить. Заметность кнопки решается размером, цветом и местом.
«Переход между экранами сделаем 700 мс с размытием фона, так дороже выглядит».
Принять с правкойСмена экрана по правилам движется, но это «долго», 400 мс, и без размытия. Размытие перерисовывается на каждом кадре и дёргается на слабых телефонах.
«Когда статус заказа меняется на „В пути“, пусть новое слово проявляется».
ПринятьДанные обновились сами, человек мог не заметить. Строка «данные обновились сами»: коротко · появление.
«Карточки товаров пусть въезжают по одной при прокрутке каталога».
ОтклонитьКаталог листают постоянно. Каждая карточка приходит с задержкой, и ничего нового это не объясняет.
«Удалённый товар пусть улетает с вращением в значок корзины».
Принять с правкойПоказать удаление правильно, но по строке «элемент уходит из списка»: уход и смыкание соседей, без вращения и полёта через экран.
«После первого заказа покажем конфетти».
Принять с правкойУкрашение в редкий момент допустимо: один раз, до секунды, не мешает нажать дальше. При «уменьшить движение» не показывается.
4Производительность: проверка и отказ
Анимация, которая дёргается на слабых телефонах, хуже анимации, которой нет.
Плавным движение выглядит при 60 кадрах в секунду, а это около 16 мс на кадр.
В это время браузер должен уложить и работу страницы, и отрисовку. Поэтому правила фиксируют не только что анимируем, но и чем:
- Двигаем сдвигом, масштабом и прозрачностью. Их браузер меняет почти даром. Ширина, высота и положение от края заставляют пересчитывать раскладку страницы на каждом кадре.
- Не анимируем тень и размытие. Если без тени никак, анимируется прозрачность слоя, на котором она нарисована.
- Не двигаем десятки элементов сразу. Сорок строк, въезжающих одна за другой, — это сорок анимаций.
- Записываем эталонный слабый телефон. Конкретную модель, самую слабую из тех, что поддерживает продукт. Анимация проверяется на нём, а не на ноутбуке дизайнера.
| Проверка перед выпуском | Как | Проходит, если |
|---|---|---|
| Свойства | Разработка называет, что меняется во время анимации | Только сдвиг, масштаб, поворот, прозрачность |
| Эталонный телефон | Пройти сценарий на нём | Рывков не видно, ввод не ждёт анимацию |
| Замедленный процессор | Chrome, инструменты разработчика → Performance → CPU: 4x slowdown | Движение остаётся плавным |
| Медленная сеть | Замедление сети в инструментах разработчика | Запрос уходит в момент нажатия |
| «Уменьшить движение» | Включить настройку в системе | Сценарий проходится и понятен |
5Когда правила меняются
Правила стареют вместе с продуктом: появляется новый тип изменения, и его вписывают в правила, а не решают по месту.
В приложении магазина появилась сортировка корзины перетаскиванием.
Такого изменения в таблице нет: элемент двигается не сам, его ведёт палец. Вот как оно попадает в правила:
- Описать изменение. Строку корзины тянут пальцем, соседи расступаются. Бывает редко, по инициативе человека.
- Поискать строку в таблице. «Мелкое изменение на месте» и «элемент уходит из списка» близко, но не то: здесь движение без длительности, оно идёт за пальцем.
- Предложить новую строку. Пока палец на экране, строка движется за ним без анимации. Соседи расступаются: коротко · перемещение. Отпустили — строка встаёт на место: коротко · перемещение. При «уменьшить движение» строка по-прежнему идёт за пальцем, соседи меняются местами сразу.
- Показать и согласовать. Прототип на двух экранах и проба в коде. Разработка подтверждает, что двигаются только сдвигом.
- Внести с датой и причиной в журнал изменений правил. Места, где уже сделали по-своему, привести к правилу.
| Дата | Что изменилось | Почему |
|---|---|---|
| 12.03 | Новая строка «элемент тянут пальцем» | Появилась сортировка корзины перетаскиванием |
| 02.02 | «Долго» 500 → 400 мс | Смена экрана на слабом телефоне ощущалась медленной |
| 15.01 | Автоматическое движение — только по нажатию | Баннеры на главной мешали читать каталог |
6Прогон чужой спецификации
Правила работают, когда по ним можно проверить чужую работу и сослаться на строку, а не на вкус.
Дизайнер соседней команды прислал спецификацию анимаций для нового раздела «Подписка на кофе».
Сверьте её с правилами магазина из раздела 1. Пять строк нарушают правила, три в порядке. Нажимайте на строки с нарушением.
- Карточка тарифа при выборе увеличивается до 105 %
- Шторка «Частота доставки» выезжает снизу
- Число «Осталось 3 доставки» подпрыгивает при изменении
- Баннер «Первый месяц −20 %» листается сам
- Переход к оформлению: экран сдвигается влево
- Статус «Подписка активна» проявляется, когда пришла оплата
- Фон раздела: кофейные зёрна плывут медленнее текста при прокрутке
- Кнопка «Оплатить» сжимается по ширине в круг и крутится
- Карточка тарифа увеличивается, 250 мс, ease.Нарушение. Выбор — это отклик на нажатие: по правилам только цвет, «быстро». К тому же 250 мс и ease не из набора. Выбранная карточка отличается рамкой и подложкой.
- Шторка «Частота доставки».В порядке. Строка «крупный элемент поверх» слово в слово, включая уход и «уменьшить движение».
- Число подпрыгивает, пружина, 600 мс.Нарушение. Мелкое изменение на месте: «быстро · перемещение». Пружины в наборе нет, 600 мс втрое дольше «коротко», а поведение при «уменьшить движение» не описано.
- Баннер листается сам.Нарушение. Автоматическое движение по правилам — только по нажатию. По WCAG то, что двигается само дольше пяти секунд рядом с другим содержимым, человек должен иметь возможность остановить, а баннер крутится, пока открыт раздел.
- Переход к оформлению.В порядке. Смена экрана вперёд: «долго · перемещение», растворение при «уменьшить движение».
- Статус «Подписка активна».В порядке. Строка «данные обновились сами».
- Зёрна плывут при прокрутке.Нарушение. Украшение в рабочем разделе, да ещё параллакс. WCAG приводит его как пример движения, без которого обычно можно обойтись. А людям с вестибулярными нарушениями от него бывает плохо. По правилам украшения только в промо и один раз.
- Кнопка сжимается в круг и крутится, 500 мс.Нарушение. Анимация ширины пересчитывает раскладку на каждом кадре — дорого. 500 мс не из набора. Загрузка по правилам — индикатор: кнопка сохраняет размер, подпись сменяется индикатором.
Все пять найдены. Каждое замечание — ссылка на строку правил, и ни одно не звучит как «мне не нравится». Так спор с соседней командой заканчивается правкой, а не обсуждением вкуса.
7Задание
Опишите правила движения продукта на одной-двух страницах: что анимируем, какими параметрами, что делаем при «уменьшить движение». Прогоните по ним один чужой макет.
Часть 1 · Инвентаризация, 30 минут
- Пройдите основные сценарии продукта и выпишите все изменения: что появляется, уходит, меняется.
- Сведите их к типам: отклик на нажатие, элемент поверх, уход из списка, смена экрана и так далее.
- Соберите все длительности и кривые, которые сейчас есть в макетах и в коде.
Часть 2 · Правила, 60 минут
- Заполните таблицу: изменение, движение, токены, поведение при «уменьшить движение».
- Опишите токены в двух слоях — базовые значения и роли — и где они живут в макете и в коде.
- Запишите проверку производительности и эталонный слабый телефон.
- Опишите, как добавляется новое: кто предлагает, кто согласует, куда пишется.
Часть 3 · Прогон, 30 минут
- Возьмите чужой макет или прототип с анимациями: коллеги, соседней команды, прошлого релиза.
- Сверьте каждую анимацию с правилами и выпишите расхождения со ссылкой на строку.
- Если сослаться не на что, отметьте это как дыру в правилах и допишите строку.
ПРАВИЛА ДВИЖЕНИЯ · ______________________ версия __ от __.__.____ 1. ЗАЧЕМ Движение объясняет изменение: откуда появилось, куда исчезло, что стало другим. В рабочих сценариях движения без изменения нет. 2. ЧТО АНИМИРУЕМ изменение | движение | токены | при «уменьшить движение» отклик на нажатие | ________ | ______ | ________________ мелкое изменение на месте | ________ | ______ | ________________ небольшой элемент поверх | ________ | ______ | ________________ крупный элемент поверх | ________ | ______ | ________________ уход из списка | ________ | ______ | ________________ смена экрана | ________ | ______ | ________________ загрузка | ________ | ______ | ________________ данные обновились сами | ________ | ______ | ________________ украшение | ________ | ______ | ________________ автоматическое | только по нажатию | — | — 3. ТОКЕНЫ длительности: fast ___ · short ___ · medium ___ · long ___ кривые: enter ______ · exit ______ · move ______ где живут: макет ____________ код ____________ 4. УМЕНЬШИТЬ ДВИЖЕНИЕ сдвиг и масштаб → ____________ автоматическое → только по нажатию что остаётся: ____________ 5. ПРОИЗВОДИТЕЛЬНОСТЬ двигаем только: сдвиг, масштаб, поворот, прозрачность эталонный слабый телефон: ____________ проверка перед выпуском: ____________ 6. КАК ДОБАВИТЬ НОВОЕ предлагает: ________ согласует: ________ описать изменение → найти строку → предложить строку → показать → внести с датой ЖУРНАЛ ИЗМЕНЕНИЙ __.__.____ — ______________________ — почему: ______________ ПРОГОН: ______________________ (чей макет) расхождение — строка правил — что исправить ______________________ — ___ — ______________________
Что должно получиться
- Правила движения на одну-две страницы.
- Токены в двух слоях с одинаковыми именами в макете и в коде.
- Прогон чужого макета: расхождения со ссылками на строки и дописанные строки, если нашлись дыры.
План работы: 30 минут на инвентаризацию, 60 на правила, 30 на прогон. Всего — около двух часов.
Частые сложности
- «Правила сковывают бренд». Бренд живёт в промо, в первом запуске, в пустых экранах. В рабочих сценариях движение служит делу, и там правила нужнее всего.
- «Разработка уже сделала по-своему». Приводите к правилам по частоте: сначала экраны, где человек бывает чаще всего. Остальное — при следующей правке.
- «У iOS и Android своё движение». Изменения и роли общие, значения платформа может подстроить под себя. В таблице это отдельная колонка, а не отдельные правила.
- «Документ никто не читает». Правила должны жить там, где работают: токены — в библиотеке макетов и в коде, ссылка на строку — в замечаниях к ревью.
8Чек-лист и ошибки
Правила движения работают, если
- Описаны изменения, а не элементы
- По каждому изменению есть движение, токены и поведение при «уменьшить движение»
- Автоматическое движение — только по нажатию
- Токены в двух слоях, имена одинаковые в макете и в коде
- Компоненты берут роли, а не числа
- Записаны проверка производительности и эталонный слабый телефон
- Есть порядок добавления нового и журнал изменений
- Замечание к чужой анимации можно сослать на строку
Что мешает
- Правила про элементы. «Шторка — 300 мс» вместо «крупный элемент поверх», и каждый новый элемент требует новой строки.
- Числа без ролей. В коде 300, в макете 280, а смысл знает только автор.
- «Уменьшить движение» потом. Строки без этой колонки, и решение принимается в коде.
- Правила без проверки. Анимация дёргается на слабом телефоне, и это выясняется после выпуска.
- Правила без хозяина. Новое решают по месту, и через полгода таблица не совпадает с продуктом.
9Три ступени темы
Это последняя ступень темы: движение перестаёт быть личным вкусом и становится частью системы.
| Ступень | Что нужно уметь | Как проверить результат |
|---|---|---|
| Junior | Отличать переход, который объясняет, от украшения; подбирать длительность под размер; выбирать кривую; не анимировать частое; описывать анимацию для разработки | Для каждого перехода можно назвать, что он помогает понять, переходов «для красоты» не осталось |
| Middle | Показывать движением, откуда появилось и куда исчезло; брать длительности и кривые из общего набора; учитывать «уменьшить движение»; помнить про медленную сеть и слабые телефоны | При включённой системной настройке интерфейс остаётся полностью работающим и понятным без движения |
| Senior — этот урок | Описать правила движения продукта: что анимируем и зачем, токены длительностей и кривых, что при «уменьшить движение», как проверяем производительность | Спор об анимации в команде закрыт ссылкой на правило |
Что почитать дальше
- MotionДва вида движения — рабочее и выразительное, — по три кривые на каждый с числами для CSS, шесть токенов длительности с назначением каждого и чек-лист проверки движения. Кривые с отскоком Carbon не использует.
- Easing and duration: tokens and specsКак устроены токены движения в большой системе: шестнадцать длительностей в четырёх группах и два набора кривых. Сверху пометка: компоненты Google уже перевели на пружины, а эту систему больше не развивают.
- Design Tokens Format Module 2025.10 и Resolver ModuleТипы duration (только «ms» или «s») и cubicBezier (четыре числа, x от 0 до 1) и составной тип transition — длительность, задержка и кривая одной записью. Пружин в формате нет. Спецификация для авторов инструментов.
- How to create high-performance CSS animations и Why are some animations slow?Что проверить в DevTools перед выпуском — запись Performance, пропущенные кадры, подсветку перерисовки — и почему анимировать стоит только transform и opacity. Справка для разработки 2020 года.
- Understanding Success Criterion 2.3.3: Animation from InteractionsТри способа выполнить критерий и определение, по которому смена цвета и прозрачности — не движение: на это опираются, когда правило про «уменьшить движение» оспаривают. Критерий уровня AAA — в споре это возражение прозвучит первым.