Контейнерные запросы и :has() — это совпадение, созданное на небесах отзывчивости. К счастью, обе эти функции появились вместе в Chromium 105. Это масштабный выпуск с двумя востребованными функциями для адаптивных интерфейсов!
Контейнерные запросы: краткий обзор
Контейнерные запросы позволяют разработчикам запрашивать у родительского селектора его размер и информацию о стиле, что позволяет дочернему элементу владеть своей адаптивной логикой стиля, независимо от того, где он находится на веб-странице.
Вместо того, чтобы полагаться на область просмотра для стилизации входных данных, таких как доступное пространство, у разработчиков теперь есть возможность запрашивать размер элементов на странице. Эта возможность означает, что компонент владеет своей логикой адаптивного стиля. Это делает компонент гораздо более устойчивым, поскольку к нему прикрепляется логика стиля, независимо от того, где он появляется на странице.
Использование контейнерных запросов
Для построения запросов к контейнеру необходимо сначала установить включение родительского элемента. Сделайте это, установив container-type
для родительского контейнера. У вас может быть карточка с изображением и текстовым содержимым, которая выглядит следующим образом:
Чтобы создать запрос к контейнеру, установите container-type
для контейнера карты:
.card-container {
container-type: inline-size;
}
Установка container-type
в inline-size
запрашивает размер родителя в линейном направлении. В латинских языках, таких как английский, это будет ширина карточки, поскольку текст движется по строкам слева направо.
Теперь мы можем использовать этот контейнер для применения стилей к любому из его дочерних элементов с помощью @container
:
.card {
display: grid;
grid-template-columns: 1fr 1fr;
}
@container (max-width: 400px) {
.card {
grid-template-columns: 1fr;
}
}
Родительский селектор :has()
Псевдокласс CSS :has()
позволяет разработчикам проверять, содержит ли родительский элемент дочерние элементы с определенными параметрами.
Например, p:has(span)
указывает на селектор абзаца ( p
), внутри которого находится span
. Вы можете использовать это для стилизации самого родительского абзаца или чего-либо внутри него. Одним из полезных примеров является figure:has(figcaption)
для стилизации элемента figure
, содержащего подпись. Вы можете узнать больше о :has()
в этой статье Джей Томпкинса .
Контейнерные запросы и :has()
Вы можете комбинировать возможности родительского выбора :has()
с возможностями родительских запросов контейнерных запросов, чтобы создать действительно динамические внутренние стили.
Давайте расширим первый пример с картой-ракетой. Что делать, если у вас есть карта без изображения? Возможно, вы хотите увеличить размер заголовка и настроить макет сетки на один столбец, чтобы он выглядел более продуманно без изображения.
В этом примере карточка с изображением имеет шаблон сетки из двух столбцов, тогда как карточка без изображения имеет макет из одного столбца. Кроме того, карточка без изображения имеет заголовок большего размера. Чтобы написать это с помощью :has()
используйте следующий CSS.
.card:has(.visual) {
grid-template-columns: 1fr 1fr;
}
Вам нужен элемент с visual
классом, к которому можно применить описанный выше стиль двух столбцов. Еще одна изящная функция CSS — :not()
. Это часть той же спецификации, что и :has()
, но она существует гораздо дольше и имеет лучшую поддержку браузеров . Вы даже можете комбинировать :has()
и :not()
, например:
.card:not(:has(.visual)) h1 {
font-size: 4rem;
}
В приведенном выше коде вы пишете селектор, который стилизует h1
внутри карты, не содержащей visual
класса. Так вы сможете очень четко настроить размер шрифта.
Собираем все это вместе
В приведенной выше демонстрации показана комбинация :has()
, :not()
и @container
, но контейнерные запросы действительно хороши, когда вы можете видеть один и тот же элемент, используемый в нескольких местах. Давайте добавим немного стиля и покажем эти карточки в сетке рядом друг с другом.
Теперь вы действительно можете увидеть мощь современного CSS. Мы можем писать четкие стили, используя целевые стили, которые строят логику поверх логики и создают действительно надежные компоненты. Благодаря тому, что эти две мощные функции появились в Chromium 105 и набирают обороты кроссбраузерной поддержки, настало такое захватывающее время для разработчика пользовательского интерфейса!