Маркетинговые команды по-прежнему копируют старые четвёрки cubic-bezier и удивляются, почему в Safari hero-анимация «липнет», тогда как в Chrome всё гладко. Функция linear() задаёт кусочно-линейный прогресс через явные пары процентов и лучше подходит к современным требованиям animation-timing-function и transition-timing-function. В 2026 году статический HTML остаётся привлекательным из-за маленьких бандлов, но кривая должна согласоваться с scroll-driven timelines, prefers-reduced-motion и планировщиком композитора WebKit. Если движение считать украшением, недооценивают доступность: при укачивании пользователей математическая красота не спасает.
Полезно читать вместе с материалами о scroll-driven анимациях и о scroll-padding для фиксированного хедера, чтобы якоря и навигация не «перелетали» цель.
Синтаксис и шаг остановок
Каждая остановка — это значение выходного прогресса и процент на входе. Совпадающие проценты дают острые углы; для асимметричного ease-out нужно минимум три внутренние точки. Держите суммарно от пяти до девяти остановок, чтобы графики в DevTools и код-ревью оставались читаемыми.
.hero-card {
transition: transform 420ms
linear(0, 0.12 8%, 0.32 24%, 0.87 68%, 1);
}
Убедитесь, что последняя остановка достигает 1 при входе 100%; иначе последние пиксели выглядят как скрытый скачок keyframes.
linear() против cubic-bezier
| Задача | cubic-bezier | linear() | Заметка |
|---|---|---|---|
| Простой fade | Отлично | Избыточно | Классических кривых достаточно. |
| Многошаговый маркетинговый overshoot | Неудобно | Естественно | Явно кодируйте отскок. |
| Синхронизация со скроллом | Жёстко | Гибко | Вход = прогресс прокрутки. |
Связка со scroll timelines
Когда animation-timeline ссылается на именованную линию прокрутки, вход — это не время, а прогресс скролла. Слишком крутой середина ощущается как двойное ускорение. Если ход меньше 400px, смягчайте середину кривой.
prefers-reduced-motion
В @media (prefers-reduced-motion: reduce) сокращайте opacity-переходы до ~120 мс или завершайте трансформации почти мгновенно через linear(0, 1). В режиме низкого энергопотребления Safari кадры группируются — лёгкий шиммер может выглядеть как баг.
@supports и запасные варианты
Сначала строка с cubic-bezier, затем переопределение внутри feature query:
@supports (animation-timing-function: linear(0, 1)) {
.hero-card { animation-timing-function: linear(0, 0.2 15%, 1); }
}
Сохраняйте порядок объявлений, чтобы минификатор не переставил их неожиданно.
Чек-лист Safari
- По возможности запись на 120 fps и подсчёт микролагов.
- Включить «Уменьшить движение» в macOS и перезагрузить без кэша.
- Проверить ноутбук в режиме энергосбережения.
- Сравнить Technology Preview и стабильный Safari.
Композитор и джанк
transform и opacity остаются на композиторе; filter blur вместе с linear() может уронить старые GPU на основной поток. Ограничьте одновременные размытия двумя элементами и сместите старты на 40 мс.
Длинные статические страницы выигрывают от containment из статей про скролл — тогда анимации не борются с поздней загрузкой шрифтов.
Передача от дизайна
Просите нормализованные графики (время 0–100 %, выход 0–1). Закрепите «brand snap» и «посадку», добавляйте промежуточные остановки, пока ошибка на самом узком вьюпорте не станет меньше 1 CSS px. Версионируйте утверждённую строку с датой, чтобы форматирование не подменило кривую.
Ежегодный motion-аудит сравнивает старые записи экрана с текущим сайтом — изменения межстрочного интервала сдвигают субъективный темп при тех же числах.
Брейкпоинты и container queries
Кривая, «острая» на 1440px, на 390px кажется вязкой: меньше пикселей за кадр. Держите --ease-hero-wide и --ease-hero-narrow, переключайте около 720px через container query.
Дисциплина will-change
Рассыпать will-change: transform — значит исчерпать память тайлов GPU на старых MacBook Air. Не больше трёх подсказок одновременно во вьюпорте, снимайте их на animationend.
Режим экономии трафика
В iOS «Экономия данных» допустимо лёгкое движение, но не тяжёлые LCP-видеокроссфейды. Третий набор токенов укорачивает дистанции и убирает blur при той же структуре linear(). Документируйте, какие ассеты меняются, чтобы не потерять контраст.
Дизайн-токены и темы
Храните строки linear() в кастомных свойствах у корня, а не inline в каждом компоненте. Централизованные токены спасают, когда маркетинг параллельно тестирует три палитры. Экспортируйте их вместе со скриншотами Storybook, чтобы визуальные регрессии проверяли ту же кривую, что и прод.
Тёмная тема должна менять не только цвета, но и интенсивность движения: ночью длинные смещения воспринимаются агрессивнее. Второй токен linear() дешевле постфактум хотфиксов из соцсетей.
CI, Percy и ловушка «почти одинаково»
Пиксельные диффы часто помечают анимации как шум. Фиксируйте время в Storyshots или ставьте animation-play-state: paused перед Percy. Укажите, какие истории должны двигаться, чтобы ревьюеры понимали, когда diff реален.
Визуальные тесты на headless Chromium в Linux не отражают путь композитора Safari. Держите хотя бы еженедельную ручную сессию на железе Apple — хватит арендованного Mac mini.
Вспомогательные технологии и фокус
linear() влияет и на фокус-переходы: слишком медленное кольцо «тянется» за курсором и сбивает с толку клавиатуру. Держите их ниже 200 мс, если параллельно идут scroll-анимации, или опирайтесь на outline-offset вместо больших translate.
Скринридеры easing не слышат, но люди с ограниченной моторикой чувствуют задержку клик→отклик. Меряйте input-to-paint: если layout thrash задерживает отрисовку, кривая ни при чём, но выглядит виноватой.
Сторонние виджеты и каскад
Чаты, cookie-баннеры и support-виджеты часто вставляют transition shorthand, который сбивает ваши linear(). Следите за специфичностью и порядком слоёв; иногда нужны :where(.page-root .hero) или @layer utilities.
Фиксируйте, где стоит !important. Заложите эскалацию к вендору или iframe с урезанной поверхностью — иначе войны специфичности съедают дизайн-часы.
Цифры для стейкхолдеров
Три жёсткие метрики успокаивают споры: максимальный вертикальный сдвиг hero (например, 24 px), доля площади одновременного blur (например, 12 % вьюпорта), верхняя граница параллельных scroll-связанных анимаций (например, четыре).
Свяжите их с бизнес-риском: время на прайсинге при дёрганье Safari или отскок на мобиле, если нет переключения container query.
В дорожной карте фиксируйте, какие linear()-токены менялись в релизе, чтобы саппорт не принимал ложные регрессии.
FAQ
Заменяет ли linear() cubic-bezier?
Нет, дополняет.
С scroll-driven анимациями?
Да, при ограниченных диапазонах и проверке композитора.
prefers-reduced-motion?
Укоротить или убрать пространственное движение.
Сколько остановок?
Ориентир пять–девять.
Субъективность easing зависит от цепочки вывода. Аренда Apple Silicon Mac mini у MacHTML (около 16,9 USD в день) воспроизводит темп кадров Safari, гамму P3 и оттенок Night Shift — то, что не увидит линуксовый скриншот-бот. Держите машину на неделю релиза, снимите рядом, затем выключите — гибче, чем новый системник под столом.
Агентства с портфелем клиентов изолируют motion-системы разными профилями macOS, чтобы не смешивать кэши шрифтов и превью-порты.
Репетиция кривых на реальном Safari
Арендуйте облачный Mac mini, чтобы проверить linear(), scroll timelines и откаты reduced-motion до продакшена.