transition: плавные переходы
transition— CSS-свойство, которое создаёт плавный переход между двумя состояниями элемента при изменении CSS-свойств (обычно по:hover,:focus,:checked, добавлении класса).
Зачем нужно
Без transition изменение свойства происходит мгновенно — элемент «перепрыгивает» в новое состояние. Transition добавляет анимацию перехода, делая интерфейс более плавным и приятным. Это самый простой и производительный способ анимации в CSS — без единой строки JavaScript и без @keyframes.
Где используется
- Hover-эффекты на кнопках, ссылках, карточках
- Плавное появление/скрытие элементов (opacity)
- Изменение цвета, размера, позиции по взаимодействию
- Плавное раскрытие аккордеонов и меню
- Анимация фокуса на инпутах
- Смена темы (светлая/тёмная)
- Анимация tooltip
- Анимация иконок и стрелок
Предпосылки
- Блочная модель — размеры
- Псевдоклассы —
:hover,:focusдля триггеров - Цвета в CSS — анимация цветов
Отдельные свойства
.element {
/* Какие свойства анимировать */
transition-property: background-color, transform, opacity;
/* Длительность перехода */
transition-duration: 300ms;
/* Функция плавности */
transition-timing-function: ease;
/* Задержка перед началом */
transition-delay: 0s;
}
transition-property
.element {
/* Конкретные свойства */
transition-property: opacity, transform;
/* Все анимируемые свойства */
transition-property: all;
/* Отключить переходы */
transition-property: none;
}
allудобен, но снижает контроль — может анимировать свойства, которые не нужно. Лучше указывать конкретные свойства.
transition-duration
.element {
transition-duration: 300ms; /* Миллисекунды */
transition-duration: 0.3s; /* Секунды */
transition-duration: 0s; /* Мгновенно (по умолчанию) */
}
Рекомендуемые значения:
- 100–150ms — микро-взаимодействия (hover на иконке)
- 200–300ms — стандартные переходы (кнопки, карточки)
- 300–500ms — крупные элементы (модальные окна, панели)
transition-timing-function
.element {
/* Встроенные функции */
transition-timing-function: ease; /* По умолчанию: медленно → быстро → медленно */
transition-timing-function: linear; /* Равномерно */
transition-timing-function: ease-in; /* Медленный старт */
transition-timing-function: ease-out; /* Медленное завершение */
transition-timing-function: ease-in-out; /* Медленные старт и конец */
/* Кастомная кривая Безье */
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); /* Material Design */
/* Шаговая функция */
transition-timing-function: steps(4, end);
}
transition-delay
.element {
transition-delay: 0s; /* Без задержки */
transition-delay: 200ms; /* Задержка 200мс */
transition-delay: -100ms; /* Начать «с середины» анимации */
}
Сокращённая запись (shorthand)
.element {
/* property duration timing-function delay */
transition: background-color 300ms ease 0s;
/* Минимум: свойство и длительность */
transition: opacity 200ms;
/* Несколько переходов через запятую */
transition:
background-color 200ms ease,
transform 300ms ease-out,
box-shadow 250ms ease;
/* Все свойства */
transition: all 300ms ease;
}
Какие свойства можно анимировать
Анимируются хорошо (на GPU)
/* Самые производительные — compositing only */
.element {
transition: opacity 300ms ease;
transition: transform 300ms ease;
}
Анимируются нормально
.element {
/* Цвета */
transition: color 200ms, background-color 200ms, border-color 200ms;
/* Размеры (вызывают reflow — осторожно) */
transition: width 300ms, height 300ms, padding 300ms;
/* Тени */
transition: box-shadow 250ms;
}
Не анимируются
display— нет промежуточных значенийfont-family— нельзя плавно сменить шрифтbackground-image— междуurlнельзя (но можно между градиентами)position— значенияstatic,relativeи т.д. дискретны
Практические примеры
Hover на кнопке
.button {
background-color: #007bff;
color: white;
padding: 10px 24px;
border: none;
border-radius: 6px;
cursor: pointer;
transition:
background-color 200ms ease,
transform 150ms ease;
}
.button:hover {
background-color: #0056b3;
transform: translateY(-2px);
}
.button:active {
transform: translateY(0);
}
Карточка с тенью
.card {
background: white;
border-radius: 12px;
padding: 24px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition:
box-shadow 300ms ease,
transform 300ms ease;
}
.card:hover {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
transform: translateY(-4px);
}
Плавный фокус поля формы
.input {
border: 2px solid #ddd;
border-radius: 4px;
padding: 8px 12px;
outline: none;
transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.input:focus {
border-color: #007bff;
box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}
Плавное появление через opacity
.fade-element {
opacity: 0;
transform: translateY(10px);
transition:
opacity 400ms ease,
transform 400ms ease;
}
.fade-element.visible {
opacity: 1;
transform: translateY(0);
}
Подчёркивание ссылки
.link {
position: relative;
text-decoration: none;
color: #007bff;
}
.link::after {
content: "";
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 2px;
background: currentColor;
transition: width 300ms ease;
}
.link:hover::after {
width: 100%;
}
Плавное появление tooltip
.tooltip {
opacity: 0;
transition: opacity 0.2s ease;
}
.tooltip.visible {
opacity: 1;
}
Производительность
/* ХОРОШО — только composite-свойства */
.element {
transition: transform 300ms ease, opacity 300ms ease;
}
/* ПЛОХО — вызывает layout/reflow */
.element {
transition: width 300ms, height 300ms, top 300ms, left 300ms;
}
/* СОВЕТ: вместо width/height анимируйте transform: scale */
.element {
transition: transform 300ms ease;
}
.element:hover {
transform: scale(1.05);
}
will-change — подсказка браузеру для оптимизации:
.element { will-change: transform, opacity; transition: transform 300ms ease; }Не злоупотребляйте — используйте только для элементов, которые точно будут анимироваться.
Частые ошибки
- Transition на
display: none→display: block— не работает:/* НЕ сработает */ .element { display: none; transition: opacity 300ms; } .element.visible { display: block; opacity: 1; } /* Используйте opacity + visibility вместо display */ - Transition в состоянии :hover, а не в базовом:
/* ОШИБКА — анимация только при наведении, не при уходе */ .element:hover { transition: background 200ms; background: red; } /* ПРАВИЛЬНО — transition в базовом состоянии */ .element { transition: background 200ms; } .element:hover { background: red; } transition: allанимирует лишнее — указывайте конкретные свойства- Слишком долгая анимация — более 500ms воспринимается как «тормоза»
- Конфликт с
animation— если оба свойства применены к одному CSS-property,animationвыигрывает
Практика
- Создать кнопку с плавным hover (цвет + сдвиг вверх)
- Сделать карточку с анимированной тенью при наведении
- Реализовать подчёркивание ссылки через
::after+ transition - Сделать плавное появление элемента (opacity + transform)
- Попробовать разные timing-function и сравнить
Связанные темы
- transform -- rotate, scale, translate — трансформации для анимации
- Keyframes — сложные многошаговые анимации
- Keyframes
- Псевдоклассы — триггеры для transition
- Практика анимаций — готовые рецепты