transition делает изменение CSS свойств плавным. Вместо мгновенного скачка при :hover или смене класса — анимация за заданное время. Добавить transition к кнопкам и карточкам — первый шаг к живому интерфейсу.

- Синтаксис transition
- timing-function — кривая скорости анимации
- transition-delay — задержка перед стартом
- Что стоит анимировать — производительность
- Готовые hover-эффекты для копирования
- transition vs animation — что выбрать
- Часто задаваемые вопросы о CSS transition
- Почему transition не работает?
- Как сделать задержку только для одного свойства?
- transition vs animation — что выбрать?
Синтаксис transition
Transition задаётся на исходном состоянии элемента, а не на :hover. Так переход будет плавным в обе стороны — при наведении и при убирании курсора.
/* transition: свойство длительность timing-function задержка */
.button {
background: #2563eb;
transition: background-color 0.3s ease;
}
.button:hover {
background: #1d4ed8;
/* Переход будет плавным 0.3s — и при наведении, и при уходе */
}
/* Несколько свойств через запятую */
.card {
transition:
transform 0.2s ease,
box-shadow 0.2s ease,
border-color 0.15s ease;
}
/* Все свойства сразу */
.element {
transition: all 0.3s ease;
/* Удобно, но менее производительно — анимирует всё */
}
/* Развёрнутая запись */
.box {
transition-property: transform;
transition-duration: 0.3s;
transition-timing-function: ease-out;
transition-delay: 0.1s;
}

timing-function — кривая скорости анимации
Timing function определяет, как меняется скорость в ходе анимации — разгоняется ли в начале, замедляется ли в конце.
.a { transition-timing-function: ease; }
/* Медленно → ускорение → замедление в конце (по умолчанию) */
.b { transition-timing-function: linear; }
/* Равномерная скорость от начала до конца */
.c { transition-timing-function: ease-in; }
/* Медленный старт → ускорение к концу */
.d { transition-timing-function: ease-out; }
/* Быстрый старт → замедление в конце (естественно выглядит) */
.e { transition-timing-function: ease-in-out; }
/* Медленно → ускорение → замедление (самый "живой" эффект) */
/* Кастомная кривая Безье */
.spring {
transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
/* Пружинный эффект — выходит за 100% и возвращается */
}
.bounce-back {
transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
/* "Упругий" эффект */
}

| Значение | Характер | Когда использовать |
|---|---|---|
ease | Плавное замедление | Большинство случаев (по умолчанию) |
linear | Равномерно | Прогресс-бар, вращение |
ease-in | Разгон | Элемент уходит со страницы |
ease-out | Торможение | Элемент появляется (выпадение) |
ease-in-out | Разгон + торможение | Слайды, переключение вкладок |
transition-delay — задержка перед стартом
/* Задержка в четвёртом параметре */
.tooltip {
opacity: 0;
transition: opacity 0.2s ease 0.4s; /* ждать 0.4s, потом 0.2s анимация */
}
/* Разные задержки для разных свойств */
.menu-item {
opacity: 0;
transform: translateY(8px);
transition:
opacity 0.3s ease 0s, /* сразу */
transform 0.3s ease 0.05s; /* с небольшой задержкой */
}
/* Каскадные задержки — элементы появляются по очереди */
.item:nth-child(1) { transition-delay: 0s; }
.item:nth-child(2) { transition-delay: 0.05s; }
.item:nth-child(3) { transition-delay: 0.10s; }
.item:nth-child(4) { transition-delay: 0.15s; }
/* Отрицательная задержка — анимация начинается "на середине" */
.item { transition: transform 0.6s ease -0.3s; }

Что стоит анимировать — производительность
Не все CSS свойства анимируются с одинаковой производительностью. GPU-ускоренные свойства работают плавно, остальные могут тормозить на слабых устройствах.
| Категория | Свойства | Производительность |
|---|---|---|
| GPU-ускоренные | transform, opacity | Отлично — не вызывают repaint |
| Хорошие | filter, background-color, color, border-color | Хорошо |
| Медленные | width, height, margin, padding | Плохо — вызывают reflow |

/* ❌ Медленно: анимируем размер */
.box {
width: 100px;
transition: width 0.3s ease;
}
.box:hover { width: 200px; }
/* ✅ Быстро: анимируем transform */
.box {
transform: scaleX(1);
transform-origin: left;
transition: transform 0.3s ease;
}
.box:hover { transform: scaleX(2); }
/* ❌ Медленно: двигаем через margin */
.item { margin-left: 0; transition: margin-left 0.3s; }
.item:hover { margin-left: 20px; }
/* ✅ Быстро: двигаем через transform */
.item { transform: translateX(0); transition: transform 0.3s; }
.item:hover { transform: translateX(20px); }
Готовые hover-эффекты для копирования
/* 1. Кнопка — подъём и тень */
.btn-lift {
background: #2563eb;
color: white;
padding: 12px 28px;
border: none;
border-radius: 8px;
cursor: pointer;
transition:
transform 0.15s ease,
box-shadow 0.15s ease,
background 0.2s ease;
}
.btn-lift:hover {
background: #1d4ed8;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(37,99,235,0.4);
}
.btn-lift:active {
transform: translateY(0);
box-shadow: none;
}
/* 2. Карточка — подъём */
.card-hover {
background: white;
border: 1px solid #e5e7eb;
border-radius: 12px;
padding: 24px;
transition:
transform 0.25s ease,
box-shadow 0.25s ease,
border-color 0.25s ease;
}
.card-hover:hover {
transform: translateY(-6px);
box-shadow: 0 16px 40px rgba(0,0,0,0.12);
border-color: #bfdbfe;
}
/* 3. Ссылка с анимированным подчёркиванием */
.link-underline {
display: inline-block;
text-decoration: none;
color: #2563eb;
position: relative;
}
.link-underline::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 2px;
background: currentColor;
transition: width 0.3s ease;
}
.link-underline:hover::after {
width: 100%;
}
/* 4. Плавное появление overlay */
.image-container {
position: relative;
overflow: hidden;
border-radius: 12px;
}
.image-container img {
display: block;
width: 100%;
transition: transform 0.4s ease;
}
.image-container:hover img {
transform: scale(1.05);
}
.image-overlay {
position: absolute;
inset: 0;
background: rgba(37, 99, 235, 0.7);
display: flex;
align-items: center;
justify-content: center;
color: white;
opacity: 0;
transition: opacity 0.3s ease;
}
.image-container:hover .image-overlay {
opacity: 1;
}
/* 5. Input фокус */
.input-animated {
border: 2px solid #e5e7eb;
border-radius: 8px;
padding: 10px 14px;
outline: none;
transition:
border-color 0.2s ease,
box-shadow 0.2s ease;
}
.input-animated:focus {
border-color: #2563eb;
box-shadow: 0 0 0 4px rgba(37,99,235,0.1);
}

transition vs animation — что выбрать
| Критерий | transition | animation |
|---|---|---|
| Триггер | Смена состояния (hover, :focus, класс) | Автоматически при загрузке |
| Контроль | Только начало и конец | Keyframes — полный контроль |
| Повторение | Нет (только туда и обратно) | Да (iteration-count) |
| Сложность | Простая — 1 строка кода | Сложная — @keyframes блок |
| Когда использовать | Hover, focus, открытие меню | Спиннеры, пульсация, слайдшоу |

Часто задаваемые вопросы о CSS transition
Почему transition не работает?
Три частые причины: 1) Transition написан на :hover, а не на базовом элементе — тогда анимация работает только при наведении, но не при убирании курсора. Всегда пиши transition на исходном состоянии. 2) Свойство не анимируется — не все CSS свойства поддерживают плавный переход (display, visibility не анимируются плавно). 3) Значения несовместимы — например, width: auto → width: 200px не анимируется (браузер не умеет считать промежуточные значения для auto).

Как сделать задержку только для одного свойства?
Перечисли свойства через запятую с разными задержками: transition: opacity 0.3s ease 0s, transform 0.3s ease 0.1s — opacity начнёт сразу, transform с задержкой 0.1s. Так создают «каскадные» эффекты, где элементы появляются один за другим.
transition vs animation — что выбрать?
Если нужно реагировать на действие пользователя (hover, click, focus) — transition. Если нужна автоматическая анимация, повторяющаяся или со сложными промежуточными состояниями — animation с @keyframes. Примеры для transition: кнопки, карточки, меню. Примеры для animation: спиннеры загрузки, пульсирующие уведомления, бегущая строка.



