CSS-анимация с keyframes: понятное руководство
Введение
CSS даёт разработчикам возможность «оживить» страницы с помощью анимаций, управляемых ключевыми кадрами (@keyframes). Анимация меняет начальное состояние HTML-элемента через набор свойств. Часто анимируют ширину, высоту, позицию, цвет и непрозрачность, но список не ограничен.
Опорная идея: определите набор ключевых состояний элемента и затем укажите, как браузер должен переходить между ними.
Важно: ключевые кадры сами по себе ничего не сделают, пока вы не привяжете их к элементу через свойство animation (или отдельных animation-*).
Что такое элемент keyframes
@keyframes — это блок, где вы задаёте состояние элемента в конкретные моменты «временной шкалы» анимации. Каждому шагу вы указываете набор CSS-свойств, которые должны применяться в этот момент.
Простая структура @keyframes:
@keyframes identifier {
from {
/* начальные стили */
}
to {
/* конечные стили */
}
}Кроме ключевых слов from/to можно использовать проценты (0% — 100%) для промежуточных состояний.
Краткое определение: @keyframes — блок, описывающий набор состояний анимации по времени.
Пример структуры keyframes
Рассмотрим задачу: анимировать зелёную прямоугольную кнопку и превратить её в синюю круглую.
Исходные ключевые кадры (как в примере):
@keyframes clickButton {
from {
background-color: springgreen;
}
to {
border-radius: 30px;
background: blue;
}
}Но сами по себе эти правила не запустят анимацию. Нужно привязать их к селектору через animation или sub-properties.
Свойство animation и его под-свойства
Для простоты достаточно знать пять под-свойств, которые чаще всего используются:
- animation-name — имя @keyframes.
- animation-duration — длительность (например, 5s, 200ms).
- animation-timing-function — кривые времени (ease, linear, ease-in, ease-out, ease-in-out, cubic-bezier(…)).
- animation-delay — задержка перед стартом.
- animation-iteration-count — сколько раз повторять (число или infinite).
Есть и другие под-свойства (animation-direction, animation-fill-mode, animation-play-state и т.д.), но вышеуказанных пяти часто хватает.
Полный пример: анимируем кнопку
Ниже — полный HTML/CSS пример со всеми отдельными под-свойствами (как в исходном материале). Код сохранён со структурой и смыслом оригинала.
Animation
Пояснение: кнопка ждёт 4 секунды (animation-delay), затем в течение 5 секунд (animation-duration) плавно меняет состояние по кривой ease-in-out и затем повторяет бесконечно (infinite).
Упрощённый синтаксис
Одну строку animation можно использовать вместо перечисления всех под-свойств:
animation: ; Сокращённый вариант для нашей кнопки:
animation: clickButton 5s ease-in-out 4s infinite;Полный пример (сокращённый):
Animation
Примечание: сокращённый синтаксис упрощает код и снижает шанс опечаток.
Подсказки по выбору timing-function
- ease-in — медленный старт, быстрый конец.
- ease-out — быстрый старт, медленный конец.
- ease-in-out — медленный старт и медленный конец.
- linear — равномерная скорость.
Выбор зависит от ощущения, которое вы хотите передать. Для органичных интерфейсных переходов чаще берут ease-in-out.
Когда использовать keyframes, а когда переходы (transition)
- transition удобен, когда нужно анимировать ответ на одно изменение состояния (например, :hover или изменение класса). Он автоматически интерполирует между текущим и новым значением.
- @keyframes нужен, когда анимация состоит из нескольких этапов, когда нужно контролировать поведение в конкретных точках времени, или когда требуется цикличность/сложный сценарий.
Пример: плавное появление при наведении — transition; возвращающаяся «пульсация» — keyframes.
Альтернативы и расширенные варианты
- Web Animations API (WAAPI): программная анимация из JavaScript с большей гибкостью и возможностью управления в рантайме (pause, reverse, playbackRate).
- SVG SMIL и анимации внутри SVG — для сложной векторной графики.
- Canvas / WebGL — когда нужна высокая производительность или сложные визуальные эффекты.
Когда выбирать: если нужно динамически изменять кривые, синхронизировать множество анимаций или управлять прогрессом — смотрите в сторону WAAPI.
Производительность и оптимизация
Важно анимировать «представимые» свойства: translate, opacity и scale чаще всего обрабатываются GPU и дают лучшие результаты. Анимирование layout-свойств (width, height, top, left) вызывает перерисовку и перерасчёт макета (reflow) и может быть дорогим.
Рекомендации:
- По возможности используйте transform: translate(), scale(), rotate() и opacity.
- Добавьте will-change только для коротких периодов (перед анимацией) и снимайте после завершения, иначе сильная нагрузка на память.
- Для больших анимаций профилируйте в DevTools.
Важно: не злоупотребляйте will-change во всей странице — это может увеличить потребление памяти.
Доступность и UX
Анимации могут вызывать неприятные ощущения у пользователей с чувствительностью к движению. Учитывайте системные настройки:
- Respect prefers-reduced-motion: используйте медленную, минимальную или отсутствующую анимацию, когда пользователь предпочитает уменьшенное движение.
Пример использования prefers-reduced-motion:
@media (prefers-reduced-motion: reduce) {
.btn {
animation: none;
}
}Советы:
- Не помешайте основному взаимодействию (focus, click) из-за длительных анимаций.
- Для информации в интерфейсе анимации должны быть вспомогательными, а не единственным способом передачи состояния.
Примеры отказа и крайние случаи
Когда анимация может «потерпеть неудачу»:
- На старых устройствах или при отключённом JavaScript (если логика зависит от JS).
- При изменении размеров окна или при редком состоянии, когда стартовая/конечная параметры конфликтуют.
- Когда анимируются неподдерживаемые свойства — эффекта не будет.
В таких ситуациях думайте о graceful degradation: сделайте так, чтобы компонент оставался функциональным и без анимации.
Контрольные списки
Для разработчика:
- Имеется @keyframes с подходящими шагами.
- Свойство animation привязано к селектору.
- Используется transform/opacity где возможно.
- Обработан prefers-reduced-motion.
- Проверена производительность в DevTools.
Для дизайнера:
- Скорость анимации соответствует интуитивному ощущению.
- Нет сильных резких рывков.
- Анимация не мешает чтению и взаимодействию.
Для QA:
- Анимация запускается/останавливается как ожидается.
- Задержки и длительности соответствуют требованиям.
- Повтор/остановка/перемотка работают.
Критерии приёмки
- Анимация соответствует макету и описанию задачи.
- На основных браузерах анимация плавная и без заметных просадок.
- Режим reduced-motion отключает или упрощает анимацию.
- Кнопка/элемент остаётся доступным (tab, screen reader читают текст).
Тесты приёмки (мини-набор)
- Ожидание: при загрузке страницы анимация запускается через заданную задержку.
- Поведение: при переходе в режим prefers-reduced-motion анимация не воспроизводится.
- Повтор: при iteration-count=infinite анимация действительно повторяется.
- Производительность: частота кадров не падает критично при обычном использовании (проверяется профайлером).
Чит-лист и мини-таблица свойств (шпаргалка)
- animation-name: имя @keyframes.
- animation-duration: 0.3s, 1s, 500ms и т.д.
- animation-timing-function: linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier(…).
- animation-delay: время перед стартом.
- animation-iteration-count: число или infinite.
- animation-direction: normal | reverse | alternate | alternate-reverse.
- animation-fill-mode: none | forwards | backwards | both.
- animation-play-state: running | paused.
Совместимость и примечания
Современные браузеры поддерживают @keyframes и свойство animation. Для очень старых браузеров могли требоваться вендорные префиксы (-webkit-), но в большинстве актуальных проектов это уже не нужно. Если ваша аудитория использует устаревшие движки, проверьте статистику по браузерам и добавьте префиксы при необходимости.
Примеры: сложные ключевые кадры
Промежуточные шаги бывают полезны для более выразительных эффектов:
@keyframes pulseAndMove {
0% { transform: translateX(0) scale(1); opacity: 1; }
40% { transform: translateX(10px) scale(1.05); opacity: 0.9; }
70% { transform: translateX(-6px) scale(0.95); opacity: 0.95; }
100% { transform: translateX(0) scale(1); opacity: 1; }
}Такую анимацию удобно использовать для привлечения внимания, но она должна быть ненавязчивой.
Модель принятия решений — когда что использовать
Mermaid-диаграмма для выбора между transition, keyframes и WAAPI:
flowchart TD
A[Нужна простая реакция на состояние?] -->|Да| B[transition]
A -->|Нет| C[Нужны сложные этапы или циклы?]
C -->|Да| D[@keyframes]
C -->|Нужно програмно управлять?| E[Web Animations API](Если mermaid не рендерится — используйте текстовую логику выше.)
Мини-глоссарий
- Keyframes: набор состояний анимации по времени.
- Animation: сокращённое свойство, привязывающее @keyframes к элементу.
- Timing-function: функция времени, определяющая скорость изменения между ключевыми кадрами.
- prefers-reduced-motion: медиа-запрос, указывающий предпочтение пользователя к меньшему количеству движений.
Резюме
CSS-анимация через @keyframes — мощный и доступный инструмент для оживления интерфейсов. Используйте shorthand animation для краткости, а transform и opacity — для производительности. Обязательно учитывайте accessibility и системные настройки пользователя.
Важно: анимация должна усиливать UX, а не мешать ему.
Image Credit: Josh Riemer/ Unsplash
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone