CSS-анимация на одном примере
У анимации две части: @keyframes, который описывает шаги, и свойство animation, которое применяет их к элементу с длительностью. Эта карточка выезжает и проявляется при загрузке страницы:
Измените код (или поменяйте длительность на 2s), и превью перезагрузится, так что вы снова увидите появление карточки. Блок @media (prefers-reduced-motion: reduce) заменяет ключевые кадры простым проявлением только для читателей, в чьей системе включено уменьшение движения.
Синтаксис @keyframes
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.08); }
100% { transform: scale(1); }
}
fromто же самое, что0%, аtoто же, что100%.- Добавляйте сколько нужно процентных шагов. Шаги с одинаковыми стилями можно записать в одну строку:
0%, 100% { ... }. - Свойство, которого нет в первом или последнем ключевом кадре, анимируется от собственного значения элемента или к нему.
- Имя (
pulse) передается вanimation-name. Регистр в нем важен, и оно не может быть ключевым словом вродеnone.
Свойства animation
| Свойство | Что задает | По умолчанию |
|---|---|---|
animation-name | какой @keyframes запускать | none |
animation-duration | длительность одного цикла | 0s |
animation-timing-function | кривая скорости между ключевыми кадрами | ease |
animation-delay | ожидание перед первым циклом (отрицательное значение начинает с середины) | 0s |
animation-iteration-count | число циклов или infinite | 1 |
animation-direction | normal, reverse, alternate, alternate-reverse | normal |
animation-fill-mode | стили до и после: none, forwards, backwards, both | none |
animation-play-state | running или paused | running |
Сокращенная запись принимает их почти в любом порядке. Правило одно: первое значение времени это длительность, второе задержка:
.loader {
animation: pulse 1.2s ease-in-out 0.2s infinite alternate both;
/* name duration timing delay count direction fill */
}
direction и fill-mode вживую
Выберите направление, режим заполнения и число повторов, затем нажмите Play. Блок сдвигается на 200px к концу дорожки. Ниже показано, где он остановился после окончания анимации:
На что смотреть:
fill-mode: none(по умолчанию): после последнего кадра блок прыгает обратно на x = 0 и снова становится янтарным.forwards: остается на последнем ключевом кадре. Сnormalэто x = 200 и зеленый; сreverseон заканчивает на x = 0 и синим, потому что последним проигрался кадрfrom.alternateс числом повторов 2 идет туда и обратно, поэтому даже сforwardsзаканчивает на x = 0.
Бесконечные циклы: индикатор загрузки
infinite повторяет анимацию бесконечно, а animation-delay у каждого дочернего элемента сдвигает их, чтобы они двигались по очереди. Делайте циклы спокойными: медленными, небольшими, без мигания.
role="status" с aria-label сообщает пользователям программ чтения с экрана, что что-то загружается, чего одни точки не говорят. Вращающийся круг разобран на странице про поворот rotate.
Пауза и управление анимациями
animation-play-state: paused замораживает анимацию там, где она есть, а running продолжает ее оттуда. Наведите курсор на полосу ниже, чтобы поставить ее на паузу:
В JavaScript element.getAnimations() возвращает запущенные CSS-анимации, у каждой есть pause(), play(), cancel() и currentTime, который можно читать и задавать. Событие animationend срабатывает, когда заканчивается не бесконечная анимация, а animationiteration в конце каждого цикла.
Уменьшение движения и никакого мигания
Два правила доступности действуют для каждой анимации:
- Уменьшение движения. Люди могут попросить систему уменьшить движение, потому что им от него становится плохо. Самый надежный прием: добавлять движение, только если о его уменьшении не просили:
@media (prefers-reduced-motion: no-preference) {
.hero-title { animation: slide-in 0.8s ease-out both; }
}
- Никакого мигания. Содержимое, которое мигает чаще трех раз в секунду, может вызвать приступ. Полностью избегайте быстрого контрастного мерцания.
Плавные анимации без рывков
По возможности анимируйте transform и opacity. Браузер применяет их без повторной раскладки страницы, поэтому они остаются плавными даже на медленных телефонах. Анимация width, height, top, left или margin пересчитывает раскладку на каждом кадре. Чтобы переместить элемент, используйте translate() со страницы про transform.
Частые ошибки
- Нет длительности.
animation: fade;ничего не делает, потому что длительность по умолчанию0s. - Имя не совпадает.
animation-nameдолжно точно совпадать с именем@keyframes, включая регистр. - Прыжок обратно в конце. Добавьте
forwards(илиboth), чтобы сохранить последний ключевой кадр. - Мерцание перед анимацией с задержкой. Во время
animation-delayэлемент показывает свои обычные стили.backwards(илиboth) применяет первый ключевой кадр во время задержки. - Перезапуск анимации тем же значением. Повторное присвоение того же
animationничего не делает. Уберите его, вызовите перерасчет раскладки (el.offsetWidth) и задайте снова, как делает кнопка Play выше. - Анимация
display. Он меняется мгновенно. Анимируйтеopacityиtransform.
Часто задаваемые вопросы
Как сделать анимацию в CSS?
Опишите шаги через @keyframes name { from { ... } to { ... } }, а затем примените их к элементу свойством animation с длительностью: animation: name 1s ease-out;. Длительность обязательна, потому что по умолчанию она 0s.
Что делает animation-fill-mode: forwards?
Сохраняет стили последнего ключевого кадра после окончания анимации. Без него элемент прыгает обратно к своим обычным стилям. backwards применяет первый ключевой кадр во время задержки, а both делает и то и другое.
Как зациклить CSS-анимацию навсегда?
Задайте animation-iteration-count: infinite или добавьте infinite в сокращенную запись: animation: spin 1s linear infinite;. Добавьте alternate, чтобы в каждом цикле анимация шла вперед, а затем назад.
Чем CSS-анимация отличается от перехода?
Переход анимирует свойство между двумя значениями, когда оно меняется, обычно при наведении или смене класса. Анимация запускается сама, как только применена, может иметь сколько угодно ключевых кадров и умеет повторяться, идти в обратную сторону и вставать на паузу.
Как поставить CSS-анимацию на паузу?
Задайте элементу animation-play-state: paused, например в :hover или через класс, который добавляет JavaScript. Если вернуть running, анимация продолжится с того места, где остановилась.
Как отключить анимации для пользователей, которые предпочитают меньше движения?
Оберните анимацию в @media (prefers-reduced-motion: no-preference) { ... } или уберите ее внутри @media (prefers-reduced-motion: reduce) { ... }. Запрос следует настройке уменьшения движения в операционной системе пользователя.