Простая анимация «проиграться один раз за столько-то секунд» — только начало. В реальных интерфейсах нужен тонкий контроль: индикатор загрузки должен крутиться бесконечно, значок уведомления — пульсировать снова и снова, элементы в списке — появляться друг за другом с нарастающей задержкой, а анимация появления — оставлять элемент в конечном состоянии, а не сбрасывать назад. Всё это задают дополнительные свойства анимации: задержка, число повторов, направление и animation-fill-mode. Освоив их, вы превратите одноразовое движение в управляемый, повторяющийся и предсказуемый эффект.
После этого урока вы сможете точно управлять поведением анимации: сколько раз она повторяется, в какую сторону идёт, когда стартует и что остаётся на экране после её завершения.
Что уже умеем / что добавим
Вы умеете описывать кадры через @keyframes и запускать анимацию свойством animation с именем и длительностью. Теперь добавим управление: задержку старта, повторы, смену направления и фиксацию конечного состояния. В сквозном проекте мы заставим значок-метку на карточке пульсировать бесконечно и закрепим появление секции в конечном виде.
Что вы узнаете в рамках статьи
- Как отложить старт анимации через
animation-delay. - Как повторять анимацию, в том числе бесконечно, через
animation-iteration-count. - Как менять направление проигрывания через
animation-direction. - Как сохранять состояние до и после анимации через
animation-fill-mode.
Ключевые термины
animation-delay— задержка перед началом анимации.animation-iteration-count— сколько раз проигрывается анимация (число илиinfinite).animation-direction— направление проигрывания (normal,reverse,alternate).animation-fill-mode— какое состояние сохраняется до старта и после конца анимации.infinite— значение для бесконечного повтора анимации.
Задержка старта: animation-delay
animation-delay откладывает начало анимации на заданное время. Это полезно, когда нужно, чтобы элемент появился не сразу, или чтобы несколько элементов возникали по очереди:
.item {
animation: appear 0.5s ease-out;
}
.item:nth-child(2) {
animation-delay: 0.1s;
}
.item:nth-child(3) {
animation-delay: 0.2s;
}
Здесь первый элемент появляется сразу, второй — с задержкой 0,1 секунды, третий — 0,2 секунды. Получается эффект «каскада»: элементы возникают друг за другом, а не разом. Задержку задают в секундах или миллисекундах, как и длительность. Обратите внимание: пока идёт задержка, по умолчанию элемент показан в своём обычном виде — это иногда нужно скорректировать через fill-mode, о котором ниже.
Повторы: animation-iteration-count
По умолчанию анимация проигрывается один раз. Свойство animation-iteration-count задаёт, сколько раз её повторить. Можно указать число или ключевое слово infinite для бесконечного повтора:
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.loader {
animation: spin 1s linear infinite;
}
Индикатор загрузки будет крутиться бесконечно: анимация spin поворачивает элемент на полный круг за секунду и повторяется без остановки. Значение infinite — стандартный приём для спиннеров, пульсаций и любых непрерывных эффектов. Заметьте linear: для равномерного вращения подходит именно линейная функция тайминга, иначе оборот будет то ускоряться, то замедляться. Если нужно конечное число повторов, вместо infinite пишут число, например 3.
Направление: animation-direction
animation-direction управляет тем, в какую сторону проигрываются кадры. По умолчанию (normal) — от начала к концу. Значение reverse проигрывает наоборот, а особенно полезно alternate — оно чередует направление на каждом повторе:
@keyframes bob {
from { transform: translateY(0); }
to { transform: translateY(-8px); }
}
.dot {
animation: bob 0.8s ease-in-out infinite alternate;
}
С alternate элемент плавно поднимается вверх (прямой проход), затем плавно опускается обратно (обратный проход) — и так бесконечно, создавая мягкое «покачивание». Без alternate он бы рывком возвращался в начало перед каждым повтором. Сочетание infinite alternate — частый приём для «дышащих», плавно колеблющихся элементов, где движение должно быть непрерывным и симметричным.
Состояние до и после: animation-fill-mode
По умолчанию после окончания анимации элемент возвращается к своему исходному стилю — как будто анимации не было. Это часто нежелательно: анимация появления должна оставить элемент видимым, а не снова спрятать. animation-fill-mode решает это:
@keyframes appear {
from { opacity: 0; }
to { opacity: 1; }
}
.section {
opacity: 0;
animation: appear 0.6s ease-out forwards;
}
Значение forwards фиксирует конечный кадр: после анимации элемент остаётся в состоянии to (видимым), а не сбрасывается к opacity: 0. Есть и backwards — оно применяет начальный кадр ещё во время задержки (до старта), что удобно вместе с animation-delay, чтобы элемент не мелькал. Значение both объединяет оба поведения. Для анимаций появления forwards — почти обязательный параметр, иначе элемент после проигрывания «пропадёт» обратно.
Применяем в проекте
Оживим значок-метку «Хит» на карточке услуги — пусть мягко пульсирует, привлекая внимание, — и закрепим появление секции в конечном виде, чтобы она не пропадала после анимации.
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.12); }
100% { transform: scale(1); }
}
.badge {
animation: pulse 1.6s ease-in-out infinite;
}
.section {
opacity: 0;
animation: appear 0.6s ease-out forwards;
}
Обновите страницу: метка «Хит» плавно пульсирует без остановки, притягивая взгляд, а секция появляется один раз и остаётся видимой благодаря forwards. Мы задали бесконечный повтор для метки и зафиксировали конечное состояние для секции — движение стало именно таким, как задумано. Теперь анимации не просто проигрываются, а ведут себя предсказуемо и осмысленно.
Частые ошибки
- Забыть
forwardsдля появления.
Безanimation-fill-mode: forwardsэлемент после анимации вернётся к исходному стилю и «пропадёт». infiniteдля эффекта появления.
Появление должно играть один раз; бесконечный повтор уместен для спиннеров и пульсаций, а не для входа.- Возврат рывком без
alternate.
Для непрерывного «туда-обратно» нуженalternate, иначе элемент будет прыгать в начало перед каждым повтором. - Мелькание при задержке.
Если анимация появления стартует с задержкой, добавьтеbackwards(илиboth), чтобы элемент не был виден до старта.
Итоги
Прекрасная работа — теперь вы управляете анимацией по-настоящему! Вы научились откладывать старт через animation-delay, повторять движение (в том числе бесконечно) с animation-iteration-count, менять направление через animation-direction и alternate, а также фиксировать состояние до и после анимации с помощью animation-fill-mode. В сквозном проекте метка на карточке ожила пульсацией, а секция стала появляться ровно один раз и оставаться на месте.
Отличный прогресс — вашими анимациями теперь можно тонко дирижировать! В следующем уроке мы разберём трансформации transform: научимся двигать, масштабировать, вращать и наклонять элементы — именно они делают анимации плавными и производительными.