Контейнерные запросы начинают появляться в стабильных браузерах, а полифил получает большое обновление.

Контейнерные запросы здесь!

Захватывающие новости: одна из самых востребованных функций разработчиков начала появляться в веб-браузерах! Начиная с Chromium 105 и Safari 16 , теперь вы можете создавать запросы к контейнерам на основе размера и использовать значения единиц запроса контейнера в этих браузерах. Чтобы еще больше упростить использование контейнерных запросов и единиц cq на основе размера, команда Aurora в Chrome усердно работала над обновлением Container Query Polyfill для поддержки большего количества браузеров и вариантов использования, чтобы вы могли чувствовать себя уверенно, используя эту мощную функцию уже сегодня.

Что такое контейнерные запросы?

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

ALT_TEXT_ЗДЕСЬ

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

Использование контейнерных запросов

Допустим, у вас есть 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