Перейти к содержанию
Educora
Продвинутый20 мин10 / 10

Переходы, анимации и CSS-переменные

Храни цвета и размеры в CSS-переменных и оживляй страницы плавными переходами и анимациями `@keyframes`, не забывая о пользователях, чувствительных к движению.

Проверь себя
В этом уроке ты узнаешь
  • Объявлять CSS-переменные, использовать их через var() и создавать с их помощью темы
  • Создавать плавные эффекты наведения с помощью transition и transform
  • Писать повторяющиеся анимации с помощью @keyframes и animation
  • Учитывать пользователей, которые хотят меньше движения, с помощью prefers-reduced-motion

Наводишь мышь на кнопку — и она не меняет цвет рывком, а мягко подсвечивается; пока что-то загружается, крутится маленький кружок; сайт одним кликом переходит на тёмную тему. Такие мелочи делают сайт «живым» и профессиональным. Это одни из самых современных возможностей CSS, и в этом уроке ты освоишь их все: переменные, переходы и анимации.

CSS-переменные

Основной цвет сайта используется в пятнадцати местах, и дизайнер хочет его поменять. Чем искать все пятнадцать мест, лучше один раз сохрани цвет в переменной. Имя CSS-переменной начинается с двух дефисов, и обычно её объявляют в :root (это элемент <html>): --brand: #6366f1;. Чтобы её использовать, пишут var(--brand). А var(--brand, blue) возьмёт запасное значение blue, если переменная не найдена.

CSS-переменные наследуются и подчиняются каскаду, как обычные свойства. Значит, если переобъявить переменную в каком-то классе, внутри этого элемента она везде получит новое значение. Именно так строят тёмную тему:

HTML
<style>
  :root {
    --brand: #6366f1;
    --bg: #ffffff;
    --text: #1e293b;
    --radius: 12px;
  }
  .dark { --brand: #f472b6; --bg: #0f172a; --text: #e2e8f0; }

  body { font-family: system-ui, sans-serif; padding: 12px;
         display: flex; align-items: flex-start; gap: 12px; }
  .card { flex: 1; padding: 0 16px 16px; background: var(--bg); color: var(--text);
          border: 2px solid var(--brand); border-radius: var(--radius); }
  .card button { padding: 8px 14px; font: inherit; color: white; border: 0;
                 background: var(--brand); border-radius: var(--radius); }
</style>

<div class="card"><h3>Light</h3><p>The same CSS rules…</p><button>Button</button></div>
<div class="card dark"><h3>Dark</h3><p>…with other variables.</p><button>Button</button></div>
Предпросмотр
Поставь --radius равным 0 или 24px — сразу изменятся все углы на обеих карточках. Задай --brand свой любимый цвет.

Переходы: `transition`

Обычно при :hover стиль меняется мгновенно. Свойство transition велит браузеру менять его плавно, во времени. Запись: transition: свойство длительность функция-времени, например transition: background-color 0.3s ease. Через запятую можно перечислить несколько свойств. Функция времени задаёт характер движения: linear — с постоянной скоростью, ease-in — медленный старт и ускорение, ease-out — быстрый старт и замедление, а ease — значение по умолчанию.

Переходы чаще всего используют вместе с transform. Это свойство изменяет элемент, не сдвигая остальную страницу: translate(x, y) перемещает его, scale(1.1) увеличивает на 10%, а rotate(45deg) поворачивает на 45°.

HTML
<style>
  body { font-family: system-ui, sans-serif; padding: 24px; background: #f1f5f9;
         display: flex; flex-wrap: wrap; gap: 20px; align-items: center; }
  .btn { padding: 12px 22px; font: inherit; color: white; background-color: #6366f1;
         border: 0; border-radius: 10px; cursor: pointer;
         transition: background-color 0.3s ease, transform 0.2s ease; }
  .btn:hover { background-color: #db2777; transform: scale(1.08); }
  .slow { transition-duration: 2s; }
  .card { width: 150px; padding: 16px; background: white; border-radius: 12px;
          box-shadow: 0 2px 6px rgb(0 0 0 / 0.15);
          transition: transform 0.3s, box-shadow 0.3s; }
  .card:hover { transform: translateY(-8px); box-shadow: 0 12px 24px rgb(0 0 0 / 0.2); }
</style>

<button class="btn">Hover me</button>
<button class="btn slow">Slow motion</button>
<div class="card">Hover this card: it lifts up.</div>
Предпросмотр
Наводи мышь на элементы и убирай её. Замени scale(1.08) на rotate(-5deg). box-shadow даёт элементу тень: когда карточка поднимается, тень тоже растёт.

Анимации: `@keyframes`

Переход работает между двумя состояниями и запускается событием (например, наведением). Анимация же запускается сама, может проходить несколько этапов и повторяться бесконечно. Сначала этапы описывают в @keyframes (from/to или 0%, 50%, 100%), затем элементу задают свойство animation: animation: имя длительность функция-времени число-повторов направление.

HTML
<style>
  body { font-family: system-ui, sans-serif; padding: 50px 24px;
         display: flex; gap: 48px; align-items: center; }
  .spinner { width: 48px; height: 48px; border: 6px solid #e2e8f0;
             border-top-color: #6366f1; border-radius: 50%;
             animation: spin 1s linear infinite; }
  .heart { font-size: 48px; animation: beat 0.8s ease-in-out infinite alternate; }
  .ball { width: 40px; height: 40px; border-radius: 50%; background: #f59e0b;
          animation: bounce 0.6s ease-in infinite alternate; }

  @keyframes spin { to { transform: rotate(360deg); } }
  @keyframes beat { from { transform: scale(1); } to { transform: scale(1.25); } }
  @keyframes bounce { from { transform: translateY(-40px); } to { transform: translateY(40px); } }
</style>

<div class="spinner"></div>
<div class="heart">❤️</div>
<div class="ball"></div>
Предпросмотр
infinite означает бесконечное повторение, а alternate — смену направления при каждом повторе. Поставь спиннеру длительность 3s, мячу — функцию linear и почувствуй разницу.

Движение приятно не всем

У некоторых людей сильные анимации вызывают головокружение и тошноту, поэтому в операционных системах есть настройка «уменьшить движение». CSS умеет её распознавать с помощью медиазапроса prefers-reduced-motion. Хороший сайт отключает или смягчает декоративные анимации для таких пользователей.

CSS
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 3s; }
  .heart, .ball { animation: none; }
  .card { transition: none; }
}
Спиннер показывает, что идёт работа, поэтому мы его не убираем, а только замедляем. А сердце и мяч — чистое украшение, их мы останавливаем.

Главное

  • CSS-переменную объявляют как --имя: значение; (обычно в :root) и используют через var(--имя).
  • Переменные наследуются: переобъявив их в классе, можно сменить целую тему.
  • transition делает изменения плавными; пиши его в основном правиле и сочетай с transform.
  • @keyframes описывает этапы, animation применяет их к элементу; infinite — бесконечный повтор.
  • Плавнее всего анимируются transform и opacity; с помощью prefers-reduced-motion учитывай тех, кто хочет меньше движения.

Проверь себя

Вопросов: 10. Каждый правильный ответ приносит XP.

1 / 10
Как использовать CSS-переменную --main-color в качестве цвета текста?