Контейнерные запросы здесь!
Захватывающие новости: одна из самых востребованных функций разработчиков начала появляться в веб-браузерах! Начиная с Chromium 105 и Safari 16 , теперь вы можете создавать запросы к контейнерам на основе размера и использовать значения единиц запроса контейнера в этих браузерах. Чтобы еще больше упростить использование контейнерных запросов на основе размера и единиц cq
, команда Aurora в Chrome усердно работала над обновлением Container Query Polyfill для поддержки большего количества браузеров и вариантов использования, чтобы вы могли чувствовать себя уверенно, используя эту мощную функцию уже сегодня.
Что такое контейнерные запросы?
Контейнерные запросы — это функция CSS, которая позволяет вам писать логику стилей, нацеленную на функции родительского элемента для стилизации его дочерних элементов. Вы можете создать действительно адаптивный дизайн на основе компонентов, запросив размер родительского элемента. Это гораздо более детальная и полезная информация, чем что-то вроде медиа-запросов , которые предоставляют только информацию о размере области просмотра.
С помощью контейнерных запросов вы можете писать повторно используемые компоненты, которые могут выглядеть по-разному в зависимости от того, где они расположены на странице. Это делает их более гибкими и отзывчивыми на разных страницах и шаблонах.
Использование контейнерных запросов
Допустим, у вас есть HTML:
<!-- card parent -->
<div class=”card-parent”>
<div class=”card>
<!-- card contents -->
…
</div>
</div>
Чтобы использовать запрос контейнера, сначала необходимо установить включение родительского элемента, который вы хотите отслеживать. Сделайте это, задав свойство container-type
или используя сокращение container
чтобы одновременно установить тип контейнера и имя контейнера.
.card-parent {
/* query the inline-direction size of this parent */
container-type: inline-size;
}
Теперь вы можете использовать правило @container
для установки стилей на основе ближайшего родителя. Для дизайна, подобного изображенному выше, где карточка может переходить из одного столбца в два столбца, напишите что-то вроде:
@container (min-width: 300px) {
.card {
/* styles to apply when the card container (.card-parent in this case) is >= 300px */
/* I.e. shift from 1-column to 2-column layout: */
grid-template-columns: 1fr 1fr;
}
}
Чтобы быть более аккуратным и понятным, дайте контейнеру родительского элемента имя:
.card-parent {
container-type: inline-size;
/* set name here, or write this in one line using the container shorthand */
container-name: card-container;
}
Затем перепишите предыдущий код так:
@container card-container (min-width: 300px) {
.card {
grid-template-columns: 1fr 1fr;
}
}
Единицы запроса контейнера
Чтобы сделать контейнерные запросы еще более полезными, вы также можете использовать значения единиц измерения на основе контейнера. В следующей таблице показаны возможные значения единиц контейнера и их соответствие размеру контейнера:
единица | относительно |
---|---|
cqw | 1% ширины контейнера запроса |
cqh | 1% высоты контейнера запроса |
cqi | 1% от встроенного размера контейнера запроса |
cqb | 1 % от размера блока контейнера запроса. |
cqmin | Меньшее значение cqi или cqb |
cqmax | Большее значение cqi или cqb |
Одним из примеров использования модулей на основе контейнеров является адаптивная типографика. Единицы просмотра (такие как vh
, vb
, vw
и vi
) можно использовать для определения размера любого элемента на экране.
.card h2 {
font-size: 15cqi;
}
Этот код сделает размер шрифта равным 15% от встроенного размера контейнера, то есть он будет увеличиваться по мере увеличения встроенного размера (ширины) или уменьшаться по мере его уменьшения. Чтобы пойти еще дальше, используйте функцию clamp()
чтобы задать минимальный и максимальный размер вашей типографики и изменить ее размер в зависимости от размера контейнера:
.card h2 {
font-size: clamp(1.5rem, 15cqi, 3rem);
}
Теперь заголовок никогда не будет больше 3rem
или меньше .5rem
, но где-то между ними он будет занимать 15% встроенного размера контейнера.
Эта демонстрация делает еще один шаг вперед и обновляет более широкие карточки, чтобы они имели меньший диапазон размеров, поскольку они представлены в виде двух столбцов.
Полифил запроса контейнера
Поскольку контейнерные запросы являются такой мощной функцией, мы хотим, чтобы вы могли чувствовать себя комфортно, включая ее в свои проекты, и знали, что поддержка браузера является важной частью этого. По этой причине мы работаем над улучшением Container Query Polyfill . Этот полифил имеет общую поддержку в:
- Фаерфокс 69+
- Хром 79+
- Край 79+
- Сафари 13.4+
Его размер в сжатом виде составляет менее 9 КБ, и он использует ResizeObserver с MutationObserver для поддержки полного синтаксиса запросов @container, который в настоящее время доступен в стабильных браузерах:
- Дискретные запросы (
width: 300px
иmin-width: 300px
). - Запросы диапазона (
200px < width < 400px
иwidth < 400px
). - Единицы относительной длины контейнера (
cqw
,cqh
,cqi
,cqb
,cqmin
иcqmax
) в свойствах и ключевых кадрах.
Использование полифилла запроса контейнера
Чтобы использовать полифилл, добавьте этот тег скрипта в заголовок вашего документа:
<script type="module">
if (!("container" in document.documentElement.style)) {
import("https://unpkg.com/container-query-polyfill@^0.2.0");
}
</script>
Вы также можете использовать службу для условной доставки полифила на основе User-Agent
или самостоятельно разместить его в своем собственном источнике.
Для лучшего взаимодействия с пользователем рекомендуется изначально использовать полифилл только для содержимого под сгибом и использовать запросы @supports
, чтобы временно заменить его индикатором загрузки, пока полифилл не будет готов его отобразить:
@supports not (container-type: inline-size) {
.container,
footer {
display: none;
}
.loader {
display: flex;
}
}
В достаточно быстрых сетях и устройствах или устройствах, которые изначально поддерживают запросы к контейнерам, этот индикатор загрузки никогда не будет отображаться.
Новые возможности Polyfill
Обновленный полифил поддерживает:
- Вложенные правила
@container
. - Поддерживается вложение правил
@container
в запросы@supports
и@media
и наоборот. - Условный CSS, такой как
@supports (container-type: inline-size)
пройдет после загрузки полифила. - Полная поддержка синтаксиса CSS (больше нет проблем с размещением комментариев в любом месте, где они синтаксически допустимы).
- Режимы вертикальной записи (через режим записи).
- Относительные единицы контейнера (
cqw
,cqh
и т. д.) поддерживаются в условиях запроса, объявлениях свойств и ключевых кадрах анимации.rem
иem
поддерживаются в условиях запроса. - Расширенный синтаксис запроса контейнера:
- Синтаксис диапазона (например
(200px < width < 400px)
). - Запросы равенства (например,
(width = 200px)
).
- Синтаксис диапазона (например
- Псевдоэлементы, такие как
::before
и::after
. - Браузеры без
:is(...)
/:where(...)
поддерживаются дополнительным обходным решением. - Запросы функций
orientation
иaspect-ratio
. - Правильная фильтрация запросов на основе функций (например, запрос
height
вcontainer: inline-size
правильно запрещен в режиме горизонтального письма). - Мутация DOM (например, элементы
<style>
и<link>
удаляются во время выполнения).
Ограничения и предупреждения Polyfill
Если вы используете полифил запроса контейнера, вам следует обратить внимание на несколько недостающих функций:
- Shadow DOM пока не поддерживается.
- Относительные единицы контейнера (например,
cqw
иcqh
) не поддерживаются в условиях запроса@media
.- Safari: относительные единицы контейнера не поддерживаются в ключевых кадрах анимации до версии 15.4.
-
calc()
,min()
,max()
или другие математические функции пока не поддерживаются в условиях запроса. - Этот полифилл работает только со встроенным CSS и CSS того же происхождения. Таблицы стилей перекрестного происхождения и таблицы стилей в iframe (если полифил не загружен вручную) не поддерживаются.
- Включение
layout
иstyle
требует базовой поддержки браузера:- Сафари 15.4+
- В настоящее время Firefox не поддерживает сдерживание стилей, но работает над этим.
Предупреждения
- Чтобы предотвратить влияние FID и CLS , полифил не дает никаких гарантий относительно того, когда произойдет первый макет, даже если он загружается синхронно, за исключением того, что он попытается избежать необоснованной задержки LCP. Другими словами, никогда не следует полагаться на него при первой покраске.
- Генерирует
ResizeObserver Loop Errors
. Оригинальный полифил тоже делает то же самое, но об этом стоит упомянуть. Это происходит потому, что размер блокаcontainer-type: inline-size
скорее всего, изменится после оценки запроса, но уResizeObserver
нет возможности сообщить ему, что нас не волнуют изменения размера блока. - Этот полифил протестирован с помощью тестов веб-платформы и достиг 70 % прохождения, поскольку некоторые функции, такие как API JavaScript, не заполняются полифилом, поэтому процент прохождения намеренно приближается к 70 %.
- Обходной путь
:where()
необходим для 2,23% пользователей браузеров старше:- Сафари 14
- Хром 88
- Край 88
- Самсунг Интернет 15
- Фаерфокс 78