Переход на одном примере
Переход говорит браузеру: когда это свойство меняется, анимируй его за такое-то время вместо мгновенной смены. Задавайте его в обычном правиле элемента, а не только в :hover:
Наведите курсор на первую кнопку: ее цвет плавно сменится на зеленый, и она поднимется на 4px за 0.4 секунды, а когда уберете указатель, тот же переход проиграется обратно. У второй кнопки transition: none, и она меняется мгновенно. Пользователи клавиатуры получают тот же эффект через :focus-visible.
Сокращенная запись transition
transition: background-color 0.3s ease-in-out 0.1s;
/* property duration timing delay */
| Полное свойство | Что задает | По умолчанию |
|---|---|---|
transition-property | какие свойства анимируются (all или список) | all |
transition-duration | как долго, в s или ms | 0s |
transition-timing-function | кривая скорости | ease |
transition-delay | ожидание перед стартом (может быть отрицательным) | 0s |
Длительность по умолчанию 0s, поэтому ничего не анимируется, пока вы ее не зададите. В сокращенной записи первое время всегда длительность, а второе задержка. Для разных настроек у разных свойств разделяйте их запятыми:
.card {
transition: transform 0.2s ease-out, box-shadow 0.4s ease-out;
}
Функции плавности рядом
Функция плавности решает, как меняется скорость во время перехода. Нажмите Play, и все семь полос пройдут одинаковое расстояние за одинаковые 1.5 секунды:
| Функция плавности | Ощущается как |
|---|---|
linear | постоянная скорость, механически |
ease (по умолчанию) | быстрый старт, мягкая остановка |
ease-in | медленный старт, быстрый конец: хорошо для уходящих элементов |
ease-out | быстрый старт, медленный конец: хорошо для появляющихся элементов |
ease-in-out | медленно в начале и в конце |
cubic-bezier(x1, y1, x2, y2) | ваша собственная кривая; y больше 1 дает перелет и возврат |
steps(n) | прыжки в n равных шагов, без промежуточных кадров |
Для эффектов наведения и меню отзывчиво ощущается ease-out с длительностью от 150ms до 300ms.
Что можно анимировать переходом
Переходом анимируются свойства, у которых есть промежуточные значения: цвета, длины (width, padding, margin), opacity, transform, box-shadow, border-radius, filter, background-color. Свойства, которые прыгают между ключевыми словами, например display или font-family, меняются мгновенно.
Чаще всего спотыкаются о height: auto: панель, которая открывается от height: 0 до height: auto, по умолчанию не анимируется, потому что браузер не вычисляет значения между 0 и «auto». Надежный обход это grid-обертка, единственная строка которой идет от 0fr до 1fr:
aria-expanded сообщает пользователям программ чтения с экрана, открыта ли панель, чего одна анимация не делает.
Код после окончания перехода
Событие transitionend срабатывает, когда переход заканчивается, по одному разу на каждое свойство. Используйте его, чтобы сделать что-то после движения, например перенести фокус или удалить элемент:
Учитывайте уменьшение движения
Некоторые люди включают в настройках системы «уменьшить движение», потому что движение на экране вызывает у них головокружение или отвлекает. Оставьте плавную смену цвета и прозрачности, а крупные перемещения уберите медиазапросом:
@media (prefers-reduced-motion: reduce) {
.btn { transition: background-color 0.2s ease; } /* no movement, only the color */
}
Плавные переходы без рывков
transform и opacity дешевле всего анимировать: браузер может двигать и растворять элемент без пересчета раскладки. Переход width, height, top или margin заставляет браузер заново раскладывать страницу на каждом кадре, и на медленных телефонах это может дергаться. Чтобы что-то сдвинуть, предпочитайте transform: translate(), а не left или margin. Функции разобраны на странице про transform.
Частые ошибки
transitionтолько в правиле:hover. Эффект анимируется при наведении, но возвращается скачком, когда наведение заканчивается. Ставьтеtransitionв базовое правило.- Длительность без единицы.
transition: opacity 300невалидно. Пишите300msили0.3s. transition: all. Анимирует каждое меняющееся свойство, включая те, которые вы не собирались анимировать, и может сделать изменения раскладки вялыми. Перечисляйте свойства.- Ожидание, что
display: noneрастворится.displayменяется мгновенно. Анимируйтеopacity(а в конце задайтеvisibility: hidden). - Переход к
height: auto. Он прыгает. Используйте прием сgrid-template-rowsвыше. - Долгие длительности для мелких взаимодействий. Все, что дольше примерно 400ms на кнопке или меню, ощущается медленным.
Часто задаваемые вопросы
Как работают переходы в CSS?
Вы указываете у элемента, какие свойства анимировать и как долго, например transition: background-color 0.3s ease;. Когда значение этого свойства меняется (через :hover, класс или JavaScript), браузер анимирует переход от старого значения к новому вместо мгновенной смены.
В каком порядке идут значения в сокращенной записи transition?
transition: property duration timing-function delay;, например transition: opacity 0.3s ease-in 0.1s;. Строгое правило одно: первое значение времени это длительность, второе задержка. Несколько переходов разделяются запятыми.
Почему не работает transition в CSS?
Частые причины: transition есть только в правиле :hover (поэтому анимация есть при наведении, а обратно стиль возвращается скачком), свойство нельзя анимировать (display или height до auto), у длительности нет единицы (0.3 вместо 0.3s) или значение меняется в тот же момент, когда элемент добавляется на страницу.
Можно ли анимировать переход к height: auto?
Обычным переходом height не во всех браузерах: для интерполяции к auto нужно новое свойство interpolate-size, которое пока поддерживается не везде. Частые обходные пути: анимировать grid-template-rows от 0fr до 1fr у grid-обертки или анимировать max-height до значения больше содержимого.
Чем transition отличается от animation в CSS?
Переход выполняется один раз, между двумя значениями, когда свойство меняется. Анимация использует @keyframes, может иметь много шагов, запускается сама при загрузке страницы и может повторяться или зацикливаться.