Главная идея
Движение в интерфейсе делает изменения понятными: вместо резкого скачка
пользователь видит, как элемент перешёл из одного состояния в другое. В CSS есть два
инструмента для этого. transition плавно «доводит» свойство от старого
значения к новому, когда что-то меняется (наведение, фокус, добавленный класс). @keyframes + animation
описывают самостоятельную анимацию по кадрам, которая запускается сама и может повторяться.
transition — это доводчик двери. Без него дверь хлопает: состояние мгновенно
перескакивает с «открыто» на «закрыто». Доводчик не меняет начало и конец — он лишь делает путь
между ними плавным. Точно так же transition не задаёт новых значений, а сглаживает
переход к тем, что уже описаны в :hover или другом состоянии.
@keyframes — это раскадровка мультфильма. Аниматор рисует ключевые кадры: 0% — герой слева, 50% — в центре, 100% — справа. Браузер, как и студия, дорисовывает промежуточные фазы сам. Анимация живёт по своему сценарию и не ждёт действия пользователя.
Как работает transition
У перехода четыре подсвойства. Запомнить их проще по вопросам: что, как долго, по какой кривой, с какой задержкой.
transition-property— что анимировать (transform,opacity,background-color… илиall).transition-duration— как долго идёт переход (180ms,0.3s). Без неё перехода нет — длительность по умолчанию0s.transition-timing-function— по какой кривой меняется скорость (ease,linear,ease-in-out,cubic-bezier()).transition-delay— задержка перед стартом.
Раскадровка перехода ширины кнопки от обычного состояния к наведённому (кривая ease):
Кривые скорости (easing)
Easing задаёт, как распределяется скорость во времени. linear — равномерно (выглядит
механически). ease (по умолчанию) — быстрый старт замедляется к концу. ease-in-out —
плавно стартует и плавно тормозит, самый «живой» для UI. cubic-bezier() — своя кривая.
Как работает @keyframes
Сначала описываем сценарий правилом @keyframes имя { … } с кадрами через from/to
или проценты 0%…100%. Затем «вешаем» его на элемент свойством animation (имя,
длительность, кривая, число повторов animation-iteration-count, поведение до/после
animation-fill-mode). Раскадровка фейда-вверх:
Когда что применять
- transition — для реакции на действие: hover/focus кнопок и карточек, раскрытие меню, смена класса.
- @keyframes — для самостоятельных эффектов: появление при загрузке, пульс, спиннер, бесконечный цикл.
- Анимируйте только
transformиopacity— они дёшевы для браузера.width,height,top,leftвызывают перерасчёт раскладки и тормозят.
Доступность: prefers-reduced-motion
Часть людей отключает анимации в системе (укачивание, вестибулярные нарушения). Уважайте их выбор
через медиазапрос prefers-reduced-motion: reduce — это та же тема доступности, что в уроке 38.
Частая ошибка
Самая частая — забыть transition-duration (или поставить переход в :hover,
а не на базовом селекторе). Тогда переход срабатывает только в одну сторону или не работает вовсе.
Базовый CSS урока
/* transition объявляем на БАЗОВОМ селекторе, чтобы переход шёл в обе стороны */
.feature-card,
.button {
transition-property: transform, opacity, background-color;
transition-duration: 180ms;
transition-timing-function: ease;
}
.feature-card:hover,
.feature-card:focus-within {
transform: translateY(-0.25rem); /* :hover задаёт ЦЕЛЬ, transition её сглаживает */
}
/* самостоятельная анимация появления через @keyframes */
.feature-card {
animation-name: fade-up;
animation-duration: 500ms;
animation-timing-function: ease-out;
animation-fill-mode: both; /* удержать стиль до старта и после финиша */
animation-iteration-count: 1;
}
@keyframes fade-up {
from { opacity: 0; transform: translateY(1rem); }
to { opacity: 1; transform: translateY(0); }
}
/* доступность: уменьшаем движение по системной настройке */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms;
animation-iteration-count: 1;
transition-duration: 0.01ms;
}
}