Анимации
Переход срабатывает, когда стиль меняется, — например, при наведении. Анимация запускается сама, может повторяться бесконечно и проходить через любое число промежуточных состояний. Так делают индикаторы загрузки, мигающие значки и появление элементов на странице.
Ключевые кадры
Анимация состоит из двух частей. Правило @keyframes с именем описывает ключевые кадры — состояния в начале (from) и в конце (to). Свойство animation подключает его к элементу и задаёт длительность:
<style>
@keyframes slide {
from { margin-left: 0; }
to { margin-left: 200px; }
}
.box { width: 60px; height: 60px; background: mediumpurple; animation: slide 2s; }
</style>
<div class="box"></div>Квадрат проехал один раз и вернулся на место. Чтобы посмотреть снова, нажмите «Сбросить» над примером.
Свойства анимации
| Свойство | Что задаёт | Пример |
|---|---|---|
animation-name | Имя из @keyframes | slide |
animation-duration | Длительность одного прохода | 2s |
animation-iteration-count | Сколько раз повторить | 3, infinite |
animation-direction | Направление | alternate — туда и обратно |
animation-timing-function | Плавность, как у переходов | ease-in-out |
animation-delay | Задержка перед стартом | 0.5s |
Всё это можно записать одной строкой animation, порядок слов почти свободный.
Повтор и направление
infinite повторяет анимацию бесконечно, alternate гоняет её туда и обратно без рывка в начало:
<style>
@keyframes pulse {
from { transform: scale(1); }
to { transform: scale(1.3); }
}
.dot { width: 40px; height: 40px; margin: 20px; border-radius: 50%; background: crimson;
animation: pulse 0.8s ease-in-out infinite alternate; }
</style>
<div class="dot"></div>Кадры в процентах
Вместо from и to можно указать любые точки в процентах от длительности. Так получается анимация из нескольких этапов:
<style>
@keyframes jump {
0%, 100% { transform: translateY(0); }
30% { transform: translateY(-40px); }
60% { transform: translateY(0); }
}
.ball { width: 40px; height: 40px; margin-top: 50px; border-radius: 50%; background: gold;
animation: jump 1.2s infinite; }
</style>
<div class="ball"></div>Одинаковые кадры перечисляют через запятую: 0%, 100%.
Остаться в конце
После окончания элемент возвращается к своим обычным стилям. animation-fill-mode: forwards оставляет его в состоянии последнего кадра:
<style>
@keyframes appear {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.note { opacity: 0; padding: 12px; background: honeydew; animation: appear 1s 0.5s forwards; }
</style>
<div class="note">Я появилась и осталась</div>Без forwards блок исчез бы снова: в основных стилях у него opacity: 0.
Меньше движения
Некоторых людей движение на экране утомляет или укачивает, и они включают в системе настройку «уменьшить движение». Медиазапрос prefers-reduced-motion позволяет её учесть:
@media (prefers-reduced-motion: reduce) {
.dot { animation: none; }
}Ход анимации можно привязать и к прокрутке страницы — об этом урок «Анимация при прокрутке».
Частая ошибка
Без длительности анимация не видна: по умолчанию animation-duration равна нулю, и всё заканчивается мгновенно.
<style>
@keyframes spin { to { transform: rotate(360deg); } }
.box { width: 50px; height: 50px; margin: 10px; display: inline-block; background: steelblue; }
.bad { animation: spin infinite linear; }
.good { animation: spin 2s infinite linear; }
</style>
<div class="box bad"></div>
<div class="box good"></div>Левый квадрат стоит, правый крутится. Если анимация не запускается, первым делом проверьте время.