Menu

Transition в CSS: длительность, плавность и задержка

Переход CSS анимирует свойство от старого значения к новому, когда оно меняется, например при наведении. Разберем сокращенную запись transition, все функции плавности рядом, что можно и что нельзя анимировать переходом, обход height: auto и уменьшение движения.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Переход на одном примере

Переход говорит браузеру: когда это свойство меняется, анимируй его за такое-то время вместо мгновенной смены. Задавайте его в обычном правиле элемента, а не только в :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 или ms0s
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, может иметь много шагов, запускается сама при загрузке страницы и может повторяться или зацикливаться.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ