</> Praktum

Главная / CSS / Свойство transition

Справочник · CSS

transition: плавный переход между состояниями

Редакция PraktumОбновлено 6 мин чтенияУровень: новичок

Свойство transition плавно меняет значение CSS-свойства, когда оно переходит из одного состояния в другое: при наведении, фокусе, добавлении класса. В короткой записи указывают свойство, длительность, функцию времени и задержку: transition: background-color .2s ease.

Коротко
  • transition: свойство длительность функция задержка.
  • Перечисляй конкретные свойства, а не all.
  • Для интерфейса обычно хватает 150–250 мс.
  • Плавнее всего анимируются transform и opacity.
  • Между display: none и block обычный переход не работает.

Минимальный пример

.button {
  background-color: #2a62d9;
  transition: background-color .2s ease, transform .2s ease;
}
.button:hover {
  background-color: #1f4fb8;
  transform: translateY(-2px);
}

При наведении фон темнеет, а кнопка приподнимается — плавно за 0,2 секунды. transition пишут в обычном состоянии элемента, а не в :hover: тогда анимация работает и при наведении, и при уходе курсора.

Части свойства

Из чего состоит transition
СвойствоЧто задаётПример
transition-propertyкакое свойство анимироватьopacity, transform
transition-durationдлительность.2s, 200ms
transition-timing-functionхарактер ускоренияease, ease-out
transition-delayзадержка перед стартом.1s

В короткой записи первое время — длительность, второе — задержка. Несколько переходов перечисляют через запятую, у каждого свои параметры.

Функции времени

transition-timing-function
ЗначениеДвижениеКогда
easeмягкий старт, быстрая середина, плавная остановкапо умолчанию, универсально
ease-outбыстрый старт, плавная остановкапоявление элементов
ease-inплавный старт, резкая остановкаисчезновение
linearпостоянная скоростьвращение, прогресс
cubic-bezier(.2, .8, .2, 1)своя криваяфирменное движение
steps(4)скачкамипокадровая анимация

Что можно анимировать

Анимируются свойства с промежуточными значениями: цвета, размеры, отступы, opacity, transform, тени. Нельзя плавно перейти между значениями без середины: display: none ↔ block, visibility переключается скачком (но умеет ждать окончания перехода), height: auto — нельзя анимировать к auto в большинстве браузеров.

/* показать и спрятать плавно, сохранив доступность */
.tooltip {
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease, visibility 0s linear .2s;
}
.tooltip.is-visible {
  opacity: 1;
  visibility: visible;
  transition: opacity .2s ease, visibility 0s;
}

Связка opacity и visibility с задержкой даёт плавное исчезновение, и при этом скрытый элемент не ловит клики и фокус. Современные браузеры начинают поддерживать переход к display: none через transition-behavior: allow-discrete, но для широкой совместимости надёжнее приём выше.

Производительность: что анимировать

/* плавно: не трогает раскладку */
.card { transition: transform .2s ease, opacity .2s ease; }
.card:hover { transform: translateY(-4px); }

/* дёргается: браузер пересчитывает раскладку каждый кадр */
.card { transition: top .2s, width .2s; }

transform и opacity браузер анимирует отдельно от раскладки, часто на видеокарте — они плавны даже на слабых телефонах. Изменение width, height, top, margin заставляет пересчитывать положение соседей на каждом кадре. Вместо top двигай через translate, вместо width — scale, где это возможно.

Почему не стоит писать transition: all

transition: all .3s анимирует любое изменение — включая размеры при смене раскладки, цвет фокуса, свойства, которые изменятся позже при доработке. Компонент начинает неожиданно «плыть». Перечисли то, что действительно должно двигаться: transition: background-color .2s, box-shadow .2s.

Какую длительность выбрать

Реакция на наведение и нажатие — 100–200 мс: дольше, и интерфейс кажется медленным. Появление панелей и раскрытие блоков — 200–300 мс. Большие перемещения по экрану — до 400–500 мс. Исчезновение обычно делают чуть быстрее появления.

Уважай просьбу о меньшем движении

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }
}

Некоторым людям от движения на экране становится плохо. В системе есть настройка «уменьшить движение», и CSS её видит. Отключай необязательные переходы — элементы всё равно меняют состояние, просто сразу.

transition или animation

transition

Переход между двумя состояниями по событию: наведение, фокус, класс. Простой и предсказуемый.

animation

Сценарий из нескольких шагов через @keyframes: может запускаться сам, повторяться, идти по кругу.

Частые ошибки

  • Пишут transition только в :hover, и при уходе курсора всё возвращается скачком.
  • Используют transition: all для сложного компонента.
  • Анимируют width, height и top вместо transform.
  • Ждут плавного перехода от display: none.
  • Делают реакцию кнопки дольше 300 мс, и интерфейс кажется тормозящим.

Доступность

Учитывай prefers-reduced-motion: необязательные переходы отключай. Не прячь информацию так, что она видна только в середине анимации. Мигание чаще трёх раз в секунду опасно для людей с фоточувствительной эпилепсией — с transition такого почти не бывает, но с повторяющимися эффектами будь осторожен.

Поддержка браузерами

transition и все его части поддерживаются всеми браузерами без префиксов. transition-behavior: allow-discrete и анимация к height: auto через interpolate-size — новые возможности, доступные пока не во всех браузерах.

Практика

Сделай карточку, которая при наведении поднимается на 4px и получает тень за 200 мс, и подсказку, которая плавно появляется и исчезает, при этом в скрытом состоянии не ловит клики. Отключи переходы для тех, кто просил меньше движения.

Показать решение
.card { transition: transform .2s ease, box-shadow .2s ease; }
.card:hover { transform: translateY(-4px); box-shadow: 0 12px 24px rgb(0 0 0 / .12); }

.tip { opacity: 0; visibility: hidden; transition: opacity .2s, visibility 0s .2s; }
.tip.is-visible { opacity: 1; visibility: visible; transition: opacity .2s, visibility 0s; }

@media (prefers-reduced-motion: reduce) {
  .card, .tip { transition: none; }
}

Открыть песочницу

Частые вопросы

Почему transition не работает?

Свойство не меняется, transition написан только в :hover, свойство нельзя анимировать (display) или указано не то имя свойства.

Можно ли плавно показать элемент с display: none?

Обычным transition — нет. Используй opacity вместе с visibility или новый transition-behavior: allow-discrete там, где он поддерживается.

Какие свойства лучше анимировать?

transform и opacity: они не заставляют пересчитывать раскладку и идут плавно даже на слабых устройствах.

Какую длительность выбрать?

150–250 мс для реакций на наведение и нажатие, 200–300 мс для появления панелей.

Где писать transition: в :hover или в обычном состоянии?

В обычном. Тогда переход сработает в обе стороны — при наведении и при уходе курсора.

Источники

Практикум по теме

Ещё в разделе CSS