оригинальная версия версия для слабовидящих контрастная версия выключить изображения включить изображения тёмная версия светлая версия RSS FEED K2 NEWS
☰☰
Пятница, 13 Март 2026 23:41

Управление состояниями и плавность без скриптов

Если первые две части нашего разговора были посвящены структуре и контексту (контейнерные запросы, @layer, @scope), то теперь пришло время поговорить о поведении. Современный CSS позволяет описывать не только то, как выглядит элемент в разные моменты, но и то, как он себя ведет при изменении состояний, обеспечивая плавность и отзывчивость на уровне, ранее доступном лишь в связке с JavaScript. Мы переходим от статичных правил к описанию динамики интерфейса.

Современный CSS: Управление состояниями и плавность без скриптов

Прокручиваемая анимация (Scroll-driven Animations): Действие, привязанное к скроллу

Раньше, чтобы анимировать шапку при прокрутке или создать индикатор прочтения статьи, мы писали JS-обработчики события scroll. Это было чревато проблемами производительности и требовало синхронизации с циклом отрисовки браузера. Теперь появился нативный способ связать анимацию напрямую с прокруткой.

Суть: Вы определяете временную шкалу анимации, которая зависит не от времени (@keyframes + animation-duration), а от прогресса прокрутки контейнера.

Пример: индикатор прогресса чтения статьи.

/* Создаем временную шкалу прокрутки для документа */
@keyframes grow-progress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

#progress-bar {
  position: fixed;
  top: 0; left: 0;
  width: 100%; height: 5px;
  background: royalblue;
  transform-origin: left;

  /* Привязываем анимацию к прокрутке */
  animation: grow-progress auto linear;
  animation-timeline: scroll(root);
}

Всего несколько строк кода — и у нас производительный, нативный индикатор, который не нагружает главный поток браузера. Это открывает огромные возможности: параллакс-эффекты, анимированные заголовки, которые меняются по мере скролла, и многое другое.

Переключения с помощью стилей (Style Queries): Анимация смены темы

Мы уже умеем реагировать на размер контейнера (container-type: inline-size). Но что, если нам нужно реагировать на стиль родителя? Например, на значение пользовательской переменной, отвечающей за тему оформления? До недавнего времени, чтобы изменить внутренности компонента при смене темы с "светлой" на "темную", приходилось вешать класс на родителя и писать громоздкие селекторы.

Стилевые запросы (@container style()) решают эту задачу элегантно. Они позволяют применять стили к элементу, основываясь на значении CSS-свойств (обычно кастомных) его контейнера.

Пример: карточка, подстраивающаяся под тему родителя.

/* Определяем тему на корневом элементе */
:root {
  --theme: light;
  --bg-color: white;
  --text-color: black;
}

/* Родитель становится контейнером для стилевых запросов */
body {
  container-name: theme;
}

.card {
  background: var(--bg-color);
  color: var(--text-color);
  border: 1px solid gray;
}

/* Если у родителя внутри body --theme: dark, меняем стили карточки */
@container theme style(--theme: dark) {
  .card {
    --bg-color: #333;
    --text-color: #eee;
    border-color: white;
    box-shadow: 0 0 10px rgba(255,255,255,0.1);
  }
}

Это делает интерфейсы по-настоящему контекстными. Компонент сам "подстраивается" под окружение, не требуя сложной логики на JavaScript для управления классами.

Плавные переходы между состояниями (Transition поведения)

Долгое время CSS-переходы (transition) работали только при смене свойств в CSS-классах. Но изменение самого DOM-дерева (добавление/удаление элементов) оставалось за кадром. Сейчас эта ситуация меняется.

@starting-style: Позволяет задать стили ДО начала перехода для элементов, которые только появляются в DOM. Раньше анимировать появление (например, плавно показать выпадающее меню с display: none) было невозможно без хаков. Теперь можно.

.dropdown {
  display: none;
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 0.3s, transform 0.3s;
}

.dropdown.open {
  display: block;
}

/* Стили ДО начала перехода */
@starting-style {
  .dropdown.open {
    opacity: 0;
    transform: translateY(-10px);
  }
}

transition-behavior: allow-discrete;: Это свойство разрешает анимировать "дискретные" свойства, такие как display, позволяя плавно "включать" и "выключать" элементы из потока. В связке с @starting-style это дает полный контроль над анимацией появления и исчезновения элементов.

CSS как язык описания пользовательского опыта

Обобщая все три части (первая, вторая и текущая), мы видим кристально четкую эволюцию. CSS превращается из "раскраски" в мощный инструмент для проектирования логики и опыта взаимодействия.

Если раньше динамика была синонимом JavaScript, то теперь:

Контекст и структура (контейнерные запросы, @layer, @scope) позволяют CSS "понимать", где находится элемент.

Поведение и состояние (Scroll-driven animations, Style Queries, продвинутые переходы) позволяют CSS "реагировать" на действия пользователя и окружение.

Это не значит, что JS больше не нужен. Но это значит, что огромный пласт задач по созданию отзывчивых, плавных и контекстных интерфейсов теперь решается проще, надежнее и производительнее — на уровне браузера. Освоение этих инструментов переводит разработчика на новый уровень: от верстки "пиксель-в-пиксель" к проектированию визуальной динамики и интерактивности, где CSS становится полноценным соавтором пользовательского опыта.

Спонсоры: