Меню
Поиск

Интерфейс и визуал · Анимация и микровзаимодействия

Как описать правила движения, чтобы спор об анимации закрывался ссылкой

Когда над продуктом работают несколько дизайнеров, движение быстро становится личным вкусом каждого. В уроке разберём, как описать правила движения: какие изменения анимируются и какими токенами, что происходит при «уменьшить движение», как отвечать на «добавим, чтобы было живее», как проверять производительность и как правила обновляются. Для практики — таблица изменений магазина кофе, токены в CSS и в формате W3C, тренажёр по просьбам команды и прогон чужой спецификации анимаций.

Пример для всего урока. Магазин кофе из уроков Junior и Middle вырос: над приложением и сайтом работают три дизайнера и две команды разработки. Набор длительностей у каждого свой, про «уменьшить движение» помнят не все, а спор «сделайте поживее» повторяется каждую неделю. Соберём правила движения так, чтобы новый дизайнер мог работать по ним без автора.

1Что анимируем, а что нет

Правила начинаются не с чисел, а со списка изменений, которые бывают в продукте, и решения по каждому.

Анимируют не элементы, а изменения.

Шторка — это «крупный элемент появляется поверх экрана», строка корзины — «элемент уходит из списка».

Изменений в продукте немного, и для каждого решение принимается один раз:

ИзменениеДвижениеТокеныПри «уменьшить движение»
Отклик на нажатие: кнопка, строкаНет, только цветбыстроБез изменений
Мелкое изменение на месте: переключатель, флажок, числоНа местебыстро · перемещениеСразу, без сдвига
Небольшой элемент поверх: меню, подсказка, плашкаВырастает от источникакоротко · появление; уход — коротко · уходПроявление
Крупный элемент поверх: шторка, диалогОт края или из центрасредне · появление; уход — коротко · уходПроявление
Элемент уходит из спискаУходит, соседи смыкаютсякоротко · уход, затем коротко · перемещениеСразу, без сдвига
Смена экрана вперёд и назадПо направлению переходадолго · перемещениеРастворение
ЗагрузкаИндикатор или каркас экранаравномерноИндикатор остаётся
Данные обновились сами: статус заказаНовое значение проявляетсякоротко · появлениеСразу
Украшение: промо, первый заказ, пустой экранОдин раз, не в рабочих сценарияхпо месту, до секундыНе показывать
Автоматическое: баннеры, видеоТолько по нажатию——

Токены в таблице — набор из урока Middle: длительности «быстро» 100 мс, «коротко» 200, «средне» 300, «долго» 400 и кривые «появление», «уход», «перемещение».

Изменения нет в таблице — движения у него нет, пока его не добавят в правила. Так «сделаю по-своему» превращается в предложение новой строки.

2Длительности и кривые в токенах

Числа движения живут в одном месте, одинаково в макете и в коде, и называются по роли.

Устройство то же, что у цвета: два слоя.

  • Базовые значения — числа с порядковыми именами;
  • роли — имена, которыми пользуются компоненты.

Компонент берёт роль, а не число. Когда меняется значение, правка идёт в одном месте.

Токены движения · CSS
: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 и инструменты разработки его уже понимают. В нём у длительности и у кривой свои типы:

Токены движения · формат DTCG
{
  "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«Добавим, чтобы было живее»

На просьбу добавить движение отвечают не вкусом, а тремя вопросами.

  1. Что оно объясняет? Какое изменение станет понятнее. «Будет живее» — не изменение.
  2. Как часто его увидят? Раз в жизни, раз в день или сорок раз за визит.
  3. Сколько оно стоит? Время человека, плавность на слабом телефоне, люди с настройкой «уменьшить движение».

Ответ бывает не только «да» и «нет». Нередко просьба разумная, а параметры надо привести к правилам.

Проверьте себя

Восемь просьб от команды. Что ответить на каждую?

Тренажёр · что ответить на просьбу
  1. «Пусть логотип на заставке крутится две секунды, это наш бренд».

  2. «Шторка фильтров пусть выезжает снизу, а не появляется разом».

  3. «Кнопка „Оформить“ пусть пульсирует, чтобы на неё чаще нажимали».

  4. «Переход между экранами сделаем 700 мс с размытием фона, так дороже выглядит».

  5. «Когда статус заказа меняется на „В пути“, пусть новое слово проявляется».

  6. «Карточки товаров пусть въезжают по одной при прокрутке каталога».

  7. «Удалённый товар пусть улетает с вращением в значок корзины».

  8. «После первого заказа покажем конфетти».

Каждый ответ — ссылка на строку таблицы из раздела 1. Если строки не нашлось, это повод обсудить правила, а не решить по месту.

4Производительность: проверка и отказ

Анимация, которая дёргается на слабых телефонах, хуже анимации, которой нет.

Плавным движение выглядит при 60 кадрах в секунду, а это около 16 мс на кадр.

В это время браузер должен уложить и работу страницы, и отрисовку. Поэтому правила фиксируют не только что анимируем, но и чем:

  • Двигаем сдвигом, масштабом и прозрачностью. Их браузер меняет почти даром. Ширина, высота и положение от края заставляют пересчитывать раскладку страницы на каждом кадре.
  • Не анимируем тень и размытие. Если без тени никак, анимируется прозрачность слоя, на котором она нарисована.
  • Не двигаем десятки элементов сразу. Сорок строк, въезжающих одна за другой, — это сорок анимаций.
  • Записываем эталонный слабый телефон. Конкретную модель, самую слабую из тех, что поддерживает продукт. Анимация проверяется на нём, а не на ноутбуке дизайнера.
Проверка перед выпускомКакПроходит, если
СвойстваРазработка называет, что меняется во время анимацииТолько сдвиг, масштаб, поворот, прозрачность
Эталонный телефонПройти сценарий на нёмРывков не видно, ввод не ждёт анимацию
Замедленный процессорChrome, инструменты разработчика → Performance → CPU: 4x slowdownДвижение остаётся плавным
Медленная сетьЗамедление сети в инструментах разработчикаЗапрос уходит в момент нажатия
«Уменьшить движение»Включить настройку в системеСценарий проходится и понятен
Дорогая анимация не попадает в продукт, как бы хорошо она ни выглядела в прототипе. Её упрощают — проявление вместо масштаба, сдвиг вместо высоты — или убирают.

5Когда правила меняются

Правила стареют вместе с продуктом: появляется новый тип изменения, и его вписывают в правила, а не решают по месту.

В приложении магазина появилась сортировка корзины перетаскиванием.

Такого изменения в таблице нет: элемент двигается не сам, его ведёт палец. Вот как оно попадает в правила:

  1. Описать изменение. Строку корзины тянут пальцем, соседи расступаются. Бывает редко, по инициативе человека.
  2. Поискать строку в таблице. «Мелкое изменение на месте» и «элемент уходит из списка» близко, но не то: здесь движение без длительности, оно идёт за пальцем.
  3. Предложить новую строку. Пока палец на экране, строка движется за ним без анимации. Соседи расступаются: коротко · перемещение. Отпустили — строка встаёт на место: коротко · перемещение. При «уменьшить движение» строка по-прежнему идёт за пальцем, соседи меняются местами сразу.
  4. Показать и согласовать. Прототип на двух экранах и проба в коде. Разработка подтверждает, что двигаются только сдвигом.
  5. Внести с датой и причиной в журнал изменений правил. Места, где уже сделали по-своему, привести к правилу.
ДатаЧто изменилосьПочему
12.03Новая строка «элемент тянут пальцем»Появилась сортировка корзины перетаскиванием
02.02«Долго» 500 → 400 мсСмена экрана на слабом телефоне ощущалась медленной
15.01Автоматическое движение — только по нажатиюБаннеры на главной мешали читать каталог
Новое число в наборе — последний вариант, а не первый. Сначала ищут подходящую строку, потом новую строку на старых токенах, и только потом новый токен.

6Прогон чужой спецификации

Правила работают, когда по ним можно проверить чужую работу и сослаться на строку, а не на вкус.

Дизайнер соседней команды прислал спецификацию анимаций для нового раздела «Подписка на кофе».

Сверьте её с правилами магазина из раздела 1. Пять строк нарушают правила, три в порядке. Нажимайте на строки с нарушением.

Подписка на кофе · спецификация анимаций
  • Карточка тарифа при выборе увеличивается до 105 %250 мс · ease
  • Шторка «Частота доставки» выезжает снизусредне · появление; уход — коротко · уход; при «уменьшить движение» — проявление
  • Число «Осталось 3 доставки» подпрыгивает при изменениипружина · 600 мс
  • Баннер «Первый месяц −20 %» листается самкаждые 4 секунды, по кругу
  • Переход к оформлению: экран сдвигается влеводолго · перемещение; при «уменьшить движение» — растворение
  • Статус «Подписка активна» проявляется, когда пришла оплатакоротко · появление; при «уменьшить движение» — сразу
  • Фон раздела: кофейные зёрна плывут медленнее текста при прокруткевсё время, пока открыт раздел
  • Кнопка «Оплатить» сжимается по ширине в круг и крутится500 мс, пока идёт оплата
  1. Карточка тарифа увеличивается, 250 мс, ease.Нарушение. Выбор — это отклик на нажатие: по правилам только цвет, «быстро». К тому же 250 мс и ease не из набора. Выбранная карточка отличается рамкой и подложкой.
  2. Шторка «Частота доставки».В порядке. Строка «крупный элемент поверх» слово в слово, включая уход и «уменьшить движение».
  3. Число подпрыгивает, пружина, 600 мс.Нарушение. Мелкое изменение на месте: «быстро · перемещение». Пружины в наборе нет, 600 мс втрое дольше «коротко», а поведение при «уменьшить движение» не описано.
  4. Баннер листается сам.Нарушение. Автоматическое движение по правилам — только по нажатию. По WCAG то, что двигается само дольше пяти секунд рядом с другим содержимым, человек должен иметь возможность остановить, а баннер крутится, пока открыт раздел.
  5. Переход к оформлению.В порядке. Смена экрана вперёд: «долго · перемещение», растворение при «уменьшить движение».
  6. Статус «Подписка активна».В порядке. Строка «данные обновились сами».
  7. Зёрна плывут при прокрутке.Нарушение. Украшение в рабочем разделе, да ещё параллакс. WCAG приводит его как пример движения, без которого обычно можно обойтись. А людям с вестибулярными нарушениями от него бывает плохо. По правилам украшения только в промо и один раз.
  8. Кнопка сжимается в круг и крутится, 500 мс.Нарушение. Анимация ширины пересчитывает раскладку на каждом кадре — дорого. 500 мс не из набора. Загрузка по правилам — индикатор: кнопка сохраняет размер, подпись сменяется индикатором.

Все пять найдены. Каждое замечание — ссылка на строку правил, и ни одно не звучит как «мне не нравится». Так спор с соседней командой заканчивается правкой, а не обсуждением вкуса.

Строки без нарушений тоже можно нажать: вы прочитаете, почему там всё в порядке, а счётчик «Найдено» не изменится.
Замечание к чужой анимации начинается со ссылки на правило. Если сослаться не на что, это либо вкус, либо дыра в правилах. Дыру закрывают новой строкой.

7Задание

Опишите правила движения продукта на одной-двух страницах: что анимируем, какими параметрами, что делаем при «уменьшить движение». Прогоните по ним один чужой макет.

Часть 1 · Инвентаризация, 30 минут

  1. Пройдите основные сценарии продукта и выпишите все изменения: что появляется, уходит, меняется.
  2. Сведите их к типам: отклик на нажатие, элемент поверх, уход из списка, смена экрана и так далее.
  3. Соберите все длительности и кривые, которые сейчас есть в макетах и в коде.

Часть 2 · Правила, 60 минут

  1. Заполните таблицу: изменение, движение, токены, поведение при «уменьшить движение».
  2. Опишите токены в двух слоях — базовые значения и роли — и где они живут в макете и в коде.
  3. Запишите проверку производительности и эталонный слабый телефон.
  4. Опишите, как добавляется новое: кто предлагает, кто согласует, куда пишется.

Часть 3 · Прогон, 30 минут

  1. Возьмите чужой макет или прототип с анимациями: коллеги, соседней команды, прошлого релиза.
  2. Сверьте каждую анимацию с правилами и выпишите расхождения со ссылкой на строку.
  3. Если сослаться не на что, отметьте это как дыру в правилах и допишите строку.
Правила движения · каркас документа
ПРАВИЛА ДВИЖЕНИЯ · ______________________     версия __ от __.__.____

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 — этот урок Описать правила движения продукта: что анимируем и зачем, токены длительностей и кривых, что при «уменьшить движение», как проверяем производительность Спор об анимации в команде закрыт ссылкой на правило
Ориентир по этой теме: любое движение в продукте можно объяснить строкой правил, а новое попадает в продукт через правила, а не мимо них.

Что почитать дальше

  • MotionIBM Carbon Design System · на английском · бесплатноДва вида движения — рабочее и выразительное, — по три кривые на каждый с числами для CSS, шесть токенов длительности с назначением каждого и чек-лист проверки движения. Кривые с отскоком Carbon не использует.
  • Easing and duration: tokens and specsMaterial Design 3 · на английском · бесплатноКак устроены токены движения в большой системе: шестнадцать длительностей в четырёх группах и два набора кривых. Сверху пометка: компоненты Google уже перевели на пружины, а эту систему больше не развивают.
  • Design Tokens Format Module 2025.10 и Resolver ModuleW3C Design Tokens Community Group · на английском · бесплатноТипы duration (только «ms» или «s») и cubicBezier (четыре числа, x от 0 до 1) и составной тип transition — длительность, задержка и кривая одной записью. Пружин в формате нет. Спецификация для авторов инструментов.
  • How to create high-performance CSS animations и Why are some animations slow?web.dev · на английском · бесплатноЧто проверить в DevTools перед выпуском — запись Performance, пропущенные кадры, подсветку перерисовки — и почему анимировать стоит только transform и opacity. Справка для разработки 2020 года.
  • Understanding Success Criterion 2.3.3: Animation from InteractionsW3C WAI · на английском · бесплатноТри способа выполнить критерий и определение, по которому смена цвета и прозрачности — не движение: на это опираются, когда правило про «уменьшить движение» оспаривают. Критерий уровня AAA — в споре это возражение прозвучит первым.