Эволюция Css: container queries, :has() и новые возможности дизайна без javascript

5 минут чтения

Современный CSS позволяет адаптировать компоненты к размеру контейнера, учитывать структуру и состояние элементов, а также вычислять значения без отдельного JavaScript-кода. Container queries и селектор :has() помогают решать типичные задачи интерфейса на уровне стилей. Они не заменяют JavaScript там, где нужны данные, события или сложная логика.

Что меняет переход от viewport-зависимого CSS к контекстному

  • Компонент может менять оформление в зависимости от доступного ему пространства, а не только ширины окна.
  • Селектор :has() позволяет выбирать элемент с учётом его потомков или соседних элементов.
  • CSS способен самостоятельно решать задачи оформления и визуальной адаптации, снижая потребность в CSS без JavaScript там, где скрипт не нужен.
  • Новые возможности дополняют медиазапросы и JavaScript, но не отменяют их для задач, связанных с данными и поведением приложения.

Как современный CSS стал учитывать контекст компонента, а не только экран

Раньше адаптивность чаще описывали через медиазапросы, которые проверяют характеристики области просмотра: например, её ширину. Это удобно для перестройки всей страницы, но не всегда подходит повторно используемым компонентам. Одна и та же карточка может оказаться в широкой колонке на одной странице и в узкой боковой панели на другой.

Контекстный подход позволяет компоненту реагировать на условия вокруг него. Container queries проверяют размер контейнера, а селектор :has() — наличие подходящих элементов в структуре документа. Вместе они помогают строить более автономные компоненты, которые можно размещать в разных частях интерфейса.

Выражение «современный CSS» здесь обозначает набор развивающихся возможностей языка, а не отдельный стандарт или режим. Эти средства отвечают за стилизацию и адаптацию; получение данных, сложные взаимодействия и прикладную логику по-прежнему обычно поручают JavaScript.

Container queries: адаптация интерфейса к размеру родительского блока

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

.card-list {
  container-type: inline-size;
}

@container (min-width: 32rem) {
  .card {
    display: grid;
    grid-template-columns: 8rem 1fr;
  }
}

В этом примере карточка меняет расположение содержимого, когда её контейнер достаточно широк. Пороговое значение нужно подбирать под конкретный компонент и его содержимое.

  1. Назначьте контейнером элемент, размер которого должен определять оформление потомков.
  2. Выберите тип контейнера. Для запросов по ширине часто используют container-type: inline-size.
  3. Добавьте правило @container с условием, например минимальной шириной.
  4. Внутри правила меняйте только те свойства, которые действительно нужны компоненту: раскладку, отступы или видимость вспомогательного элемента.
  5. Проверьте компонент в узком и широком контейнере, а не только в окне браузера разных размеров.

has() как способ описывать состояния через структуру DOM

Селектор :has() выбирает элемент, если внутри него или рядом с ним находится элемент, соответствующий условию. Это позволяет описывать некоторые состояния интерфейса непосредственно в CSS.

  • Форма: выделить группу, в которой есть поле с состоянием ошибки, например .field:has(input:invalid).
  • Карточка: изменить оформление карточки, если в ней размещён значок, предупреждение или дополнительный блок.
  • Список: оформить список иначе, если в нём есть выбранный пункт.
  • Навигация: задать стиль контейнеру, внутри которого находится текущая ссылка.

Селектор :has() удобен, когда нужное визуальное правило зависит от структуры DOM. Для демонстрации состояния ошибки он не заменяет проверку данных и управление отправкой формы.

Селекторы и функции CSS, которые сокращают зависимость от JavaScript

CSS может самостоятельно решать ряд задач представления интерфейса. Это уменьшает количество скриптов, которые нужны только для переключения классов или выбора оформления.

  • Преимущества: правило находится рядом со стилями компонента; меньше кода для чисто визуальных условий; компонент проще переиспользовать в разных контейнерах.
  • Преимущества: функции вроде clamp() помогают задавать плавно меняющиеся размеры без множества отдельных медиазапросов.

При этом у CSS есть границы: стили не заменяют прикладную логику, а условия и каскад могут усложнить отладку, если правила разбросаны по проекту.

  • Ограничения: JavaScript нужен, если требуется загрузить или преобразовать данные, обработать сложное действие пользователя либо синхронизировать состояние приложения.
  • Ограничения: поддержку конкретного свойства важно проверять для целевых браузеров и устройств; не следует предполагать, что любое новое средство доступно в любой среде.

Практические сценарии: карточки, формы и адаптивные панели без скриптов

Container queries помогают настроить карточки по ширине колонки, а :has() — стилизовать формы и контейнеры с учётом вложенных элементов. Перед внедрением проверьте несколько типичных ошибок:

  • Подмена медиазапросов контейнерными условиями без необходимости. Для перестройки всей страницы по ширине окна медиазапросы по-прежнему могут быть яснее.
  • Назначение контейнером неподходящего элемента. Убедитесь, что размер именно этого элемента отражает доступное пространство для компонента.
  • Ожидание, что CSS выполнит проверку данных. Визуально обозначить некорректное поле можно стилями, но правила валидации и обработку отправки нужно продумать отдельно.
  • Слишком сложные условия в селекторах. Если правило трудно прочитать и проверить, упростите структуру или передавайте состояние через классы и JavaScript.
  • Предположение, что «без скриптов» — цель сама по себе. Используйте CSS там, где речь об оформлении; сохраняйте JavaScript для поведения и логики приложения.

Быстрые советы перед внедрением

  • Сначала определите, от чего зависит изменение: от окна, контейнера или структуры элемента.
  • Проверьте компонент в реальных местах использования, включая узкие колонки и длинный контент.
  • Оставьте базовый стиль вне условного правила, чтобы компонент сохранял понятное оформление.
  • Изучайте примеры и курсы CSS онлайн критически: проверяйте актуальность приёмов и поддержку в проектах, для которых пишете код.

Границы новых возможностей и проверка поддержки в браузерах

Перед использованием новой возможности сверяйтесь с требованиями проекта, проверяйте поддержку целевых браузеров и тестируйте интерфейс в реальной разметке. Если нужное поведение критично, предусмотрите подходящий базовый стиль или альтернативу. Конкретный запасной вариант зависит от задачи и поддерживаемых браузеров.

Мини-сценарий: карточка в широкой колонке показывает изображение и текст рядом, а в узкой — один под другим. Задайте контейнер на родителе карточки и добавьте условие @container. Если контейнерные запросы недоступны в одной из целевых сред, базовое оформление оставьте одноколоночным.

Для состояния формы используйте :has() только для оформления, например подсветки группы с ошибочным полем. Проверку, сообщение пользователю и отправку данных реализуйте средствами, подходящими для логики приложения.

Что важно выяснить перед внедрением новых возможностей CSS

Чем container queries отличаются от медиазапросов?

Медиазапросы проверяют характеристики области просмотра или среды. Container queries позволяют применять стили в зависимости от размера контейнера компонента.

Нужно ли задавать контейнер перед использованием @container?

Да, элемент-предок нужно объявить подходящим контейнером. Затем условие запроса применяется к его потомкам.

Что выбирает селектор :has()?

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

Может ли :has() заменить JavaScript?

Только в отдельных задачах оформления, где достаточно CSS-условия. Для данных, сложного поведения и управления состоянием приложения JavaScript остаётся необходимым.

Как проверить поддержку новых возможностей CSS?

Сверьтесь с целевыми браузерами проекта и проверьте интерфейс в них. Если возможность критична, предусмотрите базовый стиль или альтернативный способ оформления.

Когда container queries полезнее медиазапросов?

Когда компонент должен адаптироваться к ширине выделенной ему области и может использоваться в контейнерах разного размера. Для изменений всей страницы по ширине окна часто достаточно медиазапросов.

Автор: Ольга Соколова