transition-property решает, какое именно CSS-свойство анимировать. Плавно меняются только свойства с промежуточными значениями - цвет, число, размер, трансформация. У «дискретных» свойств вроде display промежуточных значений нет, поэтому браузер не тянет их плавно, а просто переключает ровно на середине времени перехода.
В этом уроке
Попробуй прямо сейчас: наведи курсор на карточку - размер меняется почти мгновенно (0,3 секунды), а цвет перетекает медленно, за целых 2 секунды, потому что у каждого свойства в списке своя длительность. Поменяй местами 2s и .3s и наведи снова.
Какие свойства действительно анимируются
Браузер умеет плавно интерполировать (вычислять промежуточные значения) только для свойств, у которых значение - это число, длина, цвет или трансформация: opacity, width, margin, color, background-color, transform и похожие. Такие свойства называют интерполируемыми. У «дискретных» свойств - например, display или font-family - нет ничего среднего между двумя значениями: нельзя быть «наполовину block, наполовину none». По спецификации браузер держит начальное значение до середины времени перехода, а затем резко переключает на конечное - то есть transition на них технически срабатывает, просто без единой промежуточной картинки.
.card {
transition: transform .3s, opacity .3s;
}
.card:hover {
transform: scale(1.05);
opacity: .8;
} - оба свойства интерполируемые, оба меняются плавно, кадр за кадром.
Неправильное ожидание - что transition сделает плавным исчезновение через display:
.menu {
transition: display .3s;
}
.menu.hidden {
display: none;
} - меню останется видимым почти до половины времени перехода, а потом мгновенно исчезнет; никакого плавного затухания не будет.
transition-property: all и список из нескольких свойств
Значение по умолчанию у transition-property - all: браузер следит сразу за любым изменением любого анимируемого свойства элемента. Это удобно для быстрого прототипа, но непредсказуемо на практике - если у элемента поменяется ещё какое-то свойство (например, при изменении контента или через скрипт), оно тоже неожиданно начнёт анимироваться. Явное перечисление свойств через запятую даёт полный контроль над тем, что именно анимируется - и позволяет задать каждому свойству свою длительность по позиции в списке.
transition-property: background-color, transform;
transition-duration: .3s, .6s; - фон меняется за 0,3 секунды, трансформация - за 0,6; каждое свойство получает длительность по своей позиции в списке.
Неправильное ожидание - что при разной длине списков анимируется только часть свойств:
transition-property: width, height, color;
transition-duration: 1s; - значений duration меньше, чем свойств, поэтому браузер зацикливает список заново: все три свойства получат transition-duration ровно 1s, ни одно не останется без анимации.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
Ждать, что transition: display .3s; сделает исчезновение плавным |
display - дискретное свойство: оно держится на старом значении до 50% времени перехода, а потом мгновенно переключается - плавности нет вообще | Анимировать opacity и/или transform, а к display переходить отдельно, уже после анимации |
| Указать в transition-property больше свойств, чем значений в transition-duration | Короткий список duration зацикливается заново, а не «заканчивается» - лишние свойства просто получают повторяющиеся значения по кругу | Либо задать duration для каждого свойства явно, либо намеренно опираться на цикличность, если длительность у всех одинаковая |
| Перепутать порядок свойств между transition-property и transition-duration | Каждое значение duration/timing-function привязывается к свойству по позиции в списке, а не по имени - можно случайно назначить не ту скорость не тому свойству | Писать оба списка строго в одинаковом порядке, свойство за свойством |
| Ожидать, что transition-property: all анимирует и CSS-переменные (--custom-свойства) | Обычная переменная хранится браузером как текст, а не как число или цвет, поэтому даже под all она не интерполируется, а меняется мгновенно | Объявить тип переменной через @property с описанием синтаксиса - это отдельная, более сложная тема |
Шпаргалка
| Значение transition-property | Что означает |
|---|---|
| all (по умолчанию) | Анимировать любое изменение любого свойства, которое вообще можно анимировать |
| none | Не анимировать ничего - явно отключает transition |
| Одно свойство | transition-property: opacity; - анимируется только оно |
| Несколько через запятую | transition-property: opacity, transform; - у каждого своя длительность по позиции |
| Списки разной длины | Более короткий список duration/delay/timing-function зацикливается; лишние значения, если он длиннее, отбрасываются |
Коротко: отвечаем на вопросы
Чем плохо просто всегда писать transition-property: all?
Тем, что это непредсказуемо: all заставляет браузер следить сразу за любым изменением любого анимируемого свойства элемента, включая то, которое поменялось не по твоей воле - например, из-за resize окна, смены контента или чужого скрипта. Явно перечисленные свойства анимируются только тогда, когда это действительно нужно.
Можно ли анимировать несколько свойств одновременно с разной скоростью?
Да, именно для этого и существует список через запятую: transition-property: opacity, transform; в паре с transition-duration: .3s, .6s задаёт первому свойству одну длительность, второму - другую, по их позиции в списке.
Можно ли анимировать через transition обычную CSS-переменную (--custom-свойство)?
Сама по себе - нет: браузер хранит значение обычной переменной как текст и не знает, что это число или цвет, поэтому интерполировать его не может. Чтобы переменная стала анимируемой, её нужно заранее объявить через @property, явно указав тип значения - это уже отдельная, более продвинутая техника.