animation - это сокращённая запись сразу восьми animation-свойств одной строкой: имя, длительность, кривая, задержка, число повторов, направление, поведение до/после и пауза/запуск. Через запятую в этом же свойстве можно перечислить несколько независимых анимаций сразу на одном элементе - у каждой будет собственный полный набор параметров.
В этом уроке
Попробуй прямо сейчас: значок появляется двумя независимыми анимациями сразу, перечисленными через запятую в одном свойстве animation - fadeIn плавно проявляет прозрачность, slideUp одновременно поднимает значок снизу вверх, но стартует с задержкой в 0.3s (второе по порядку временное значение в её записи). Обе анимации написаны по правилу "имя анимации - последним словом", а fill-mode: forwards в каждой удерживает конечное состояние, а не откатывает его назад.
Восемь параметров одной строкой: порядок и подводные камни
Шорткад animation заменяет собой восемь отдельных animation-свойств, но браузер не спрашивает, в каком порядке их писать словами - он сам разбирает список по типу и позиции значений. Есть только два по-настоящему жёстких правила. Первое: если в записи ДВА значения с единицей времени (например 1s и 0.3s), ПЕРВОЕ по счёту всегда становится animation-duration, а ВТОРОЕ - animation-delay, независимо от того, где среди них стоит имя анимации. Второе: ключевые слова (ease/linear и другие кривые, normal/reverse/alternate, none/forwards/backwards/both, running/paused) браузер сопоставляет с набором допустимых значений каждого свойства по очереди - и если слово можно понять как значение одного из НИХ, оно достанется именно этому свойству, а не имени анимации.
Из второго правила есть практическое следствие, которое легко не заметить: если назвать @keyframes словом, совпадающим с одним из этих ключевых слов (например "reverse" - это ещё и допустимое значение animation-direction), браузер отдаст это слово чужому свойству, а animation-name останется в значении по умолчанию none. Собственная проверка это подтвердила: при 'animation: 2s reverse' с блоком @keyframes reverse анимация не запустилась вообще - animation-direction стал reverse, а имя анимации так и осталось none. Поэтому в этом же курсе имя анимации через animation-name и в шорткаде лучше ставить последним словом - тогда его точно не перепутают с чужим ключевым словом.
.badge {
animation: 1s ease-out 0.3s forwards slideUp;
} - порядок: 1s (первое время = duration), ease-out (кривая), 0.3s (второе время = delay), forwards (fill-mode), slideUp - имя, последним словом.
Отдельная ловушка - шорткад, написанный ПОСЛЕ отдельного animation-play-state в том же правиле:
.icon {
animation-play-state: paused;
animation: 2s infinite spin;
} - итоговый play-state будет running, а не paused: шорткад неявно выставляет ВСЕ восемь параметров, включая play-state по умолчанию, даже если сам его не упоминает. Это прямое продолжение урока про animation-play-state - если нужно и то, и другое, отдельный animation-play-state нужно писать ПОСЛЕ шорткада, а не до него.
Несколько анимаций через запятую
В свойстве animation через запятую можно перечислить сколько угодно независимых анимаций на одном элементе - каждая часть списка получает СОБСТВЕННЫЙ полный набор из восьми параметров, никак не завися от соседних. Именно так значок в блокноте выше одновременно проявляется (fadeIn) и поднимается снизу (slideUp) - это буквально две разные анимации, просто перечисленные через запятую в одной строке вместо двух отдельных объявлений animation-name/animation-duration и так далее.
.badge {
animation: 1s ease-out forwards fadeIn,
1s ease-out 0.3s forwards slideUp;
} - две анимации через запятую, у каждой свои duration/timing-function/delay/fill-mode/имя. Перенос строки после запятой ничего не меняет, только для читаемости.
Если несколько анимаций через запятую меняют ОДНО и то же CSS-свойство (например обе трогают width), выигрывает не сумма и не первая, а последняя в списке:
.box {
animation: 4s growWidth, 4s shrinkWidth;
}
/* growWidth растит width, shrinkWidth уменьшает -
ожидание, что они как-то "усреднятся" */ - на деле побеждает shrinkWidth, потому что она последняя по списку, как при обычном каскаде.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Считать, что первое временное значение всегда относится к тому свойству, рядом с которым стоит по смыслу | На самом деле первое время - всегда duration, второе - всегда delay, независимо от позиции имени анимации | Всегда писать оба времени подряд и помнить: первое - duration, второе - delay |
| Называть @keyframes словом, которое совпадает с ключевым словом другого animation-свойства (например "reverse") | Слово достаётся чужому свойству, animation-name остаётся none, анимация не запускается вообще | Выбирать для @keyframes уникальные имена и ставить animation-name последним словом в шорткаде |
| Писать шорткад animation ПОСЛЕ отдельного animation-play-state (или другого longhand) в одном правиле | Шорткад неявно сбрасывает все восемь параметров к значениям по умолчанию, включая play-state - paused станет running | Писать нужный longhand ПОСЛЕ шорткада, если его значение должно "победить" |
| Ждать, что несколько анимаций на одно и то же CSS-свойство через запятую как-то суммируются | На деле действуют обычные правила каскада - побеждает последняя анимация в списке | Не назначать двум одновременным анимациям одно и то же CSS-свойство, если результат не последняя из них |
Шпаргалка
| Запись | Что означает |
|---|---|
| animation: 2s ease-in-out 0.5s infinite spin; | duration 2s, timing-function ease-in-out, delay 0.5s, iteration-count infinite, имя spin |
| Первое время | Всегда animation-duration |
| Второе время | Всегда animation-delay |
| Имя анимации - последним словом | Не спутается с ключевыми словами других animation-свойств |
| animation: A, B; | Две независимые анимации на одном элементе, каждая со своим полным набором параметров |
| Обе анимации меняют одно CSS-свойство | Побеждает последняя в списке |
| Шорткад animation после отдельного longhand | Сбрасывает этот longhand к значению по умолчанию |
Коротко: отвечаем на вопросы
Обязательно ли писать все восемь значений в шорткаде animation?
Нет, можно указать только нужные - остальные примут значения по умолчанию (name: none, duration: 0s, timing-function: ease, delay: 0s, iteration-count: 1, direction: normal, fill-mode: none, play-state: running). Именно поэтому шорткад, написанный после отдельного longhand-свойства в том же правиле, "стирает" его обратно к умолчанию - он неявно выставляет вообще все восемь параметров.
Можно ли перепутать порядок ключевых слов, например написать forwards раньше ease-out?
Порядок между самими ключевыми словами не важен - браузер сопоставляет каждое слово с набором допустимых значений своего свойства (у ease-out и forwards разные наборы значений, спутать их невозможно). Важен только порядок ДВУХ временных значений между собой (первое - duration, второе - delay) и то, что имя анимации может "проиграть" чужому ключевому слову, если совпадает с ним по написанию.