Начиная с 2023 года CSS Container Queries поддерживаются всеми основными браузерами. Это означает, что технология перестала быть экспериментальной и готова к использованию в продакшене.
Но что именно решают container queries, какие проблемы они закрывают и заменяют ли они media queries?
В этой статье мы разберём container queries на уровне архитектуры интерфейсов, а не просто синтаксиса: от проблемы адаптивных макетов до вложенных контейнеров, новых единиц измерения и style queries.
Проблема media queries в компонентных макетах



Media queries позволяют адаптировать интерфейс под размер viewport. Это хорошо работает для страниц целиком, но начинает ломаться, когда мы проектируем интерфейс из независимых компонентов.
Рассмотрим пример новостной ленты:
- основная колонка с новостями
- сайдбар со списком популярных статей
- карточки статей с изображением, заголовком и описанием
На десктопе:
- есть большая «featured»-статья
- ниже — горизонтальные карточки
- ещё ниже — компактные вертикальные карточки
На мобильных устройствах:
- все карточки выглядят одинаково
- изображения располагаются сверху
- горизонтальная компоновка исчезает
На планшетах:
- появляется промежуточный вариант
- часть карточек горизонтальные, часть вертикальные
В итоге один и тот же компонент статьи должен существовать в нескольких вариантах, в зависимости не только от размера экрана, но и от того, где именно он находится в макете.
Почему media queries здесь не подходят
Если строить такой интерфейс на media queries:
- приходится ориентироваться только на viewport
- компоненты «не знают», сколько у них реально места
- появляются отдельные версии одного и того же компонента
- CSS быстро разрастается и становится сложным в поддержке
Проблема в том, что viewport ≠ доступное пространство.
Компонент может быть узким даже на большом экране — например, внутри сайдбара или вложенной сетки.
Именно здесь и возникает необходимость в container queries.
Контейнерные запросы особенно полезны в интерфейсах, где важно избегать резких скачков макета при загрузке контента. Именно такие сдвиги напрямую влияют на Core Web Vitals — в частности, на показатель LCP. Подробнее о том, как оптимизация визуального контента помогает ускорить Largest Contentful Paint, мы разбирали в отдельной статье.
Что такое CSS Container Queries
Container Queries позволяют применять стили к элементам в зависимости от размера их контейнера, а не окна браузера.
Проще говоря:
компонент адаптируется к тому пространству, в котором он реально находится
Это делает адаптивность:
- локальной
- модульной
- независимой от внешнего контекста
Container queries особенно полезны в:
- компонентных дизайн-системах
- UI-библиотеках
- сложных grid- и layout-структурах
Создание контейнера
Прежде чем писать container query, нужно объявить контейнер.


В примере с новостной лентой каждый элемент списка (li) будет контейнером для статьи.
HTML-структура
<ul class="grid">
<li class="article-container">
<article>...</article>
</li>
<li class="article-container">
<article>...</article>
</li>
<li class="article-container">
<article>...</article>
</li>
</ul>
Объявление контейнера в CSS
Контейнер создаётся с помощью двух свойств:
container-typecontainer-name(необязательное, но рекомендуемое)
.article-container {
container-name: article;
container-type: inline-size;
}
📌 Почему inline-size, а не width?inline-size — это логическое свойство. В горизонтальном режиме письма оно соответствует ширине, а в вертикальном — высоте. Это делает код более универсальным.
На момент написания статьи block-size (высота) нельзя использовать в container queries.
Сокращённая запись
Можно использовать shorthand:
.article-container {
container: article / inline-size;
}
Запросы к контейнеру
Синтаксис container queries похож на media queries.
Без указания имени контейнера
@container (width > 700px) {
/* применится к ближайшему контейнеру */
}
С указанием имени контейнера
@container article (inline-size > 700px) {
/* применится только к контейнеру article */
}
Использование именованных контейнеров особенно важно, когда на странице есть несколько вложенных контейнеров.
Пример: адаптивная статья как компонент
.article-container {
container: article / inline-size;
}
article {
display: grid;
gap: 1rem;
}
@container article (inline-size > 500px) {
article {
grid-template-columns: 1fr 2fr;
}
}
@container article (inline-size > 800px) {
article {
grid-template-columns: 1fr 1fr;
gap: 2rem;
font-size: 1.2rem;
}
h3 {
font-size: 2rem;
}
}
Один и тот же компонент автоматически:
- становится вертикальным в узком контейнере
- горизонтальным — в среднем
- более «воздушным» — в широком
Без привязки к viewport.
Новый синтаксис диапазонов
Container queries используют range-синтаксис, который постепенно вытесняет min-width и max-width.
/* старый вариант */
@container (min-width: 700px) and (max-width: 900px) {}
/* новый вариант */
@container (700px <= width <= 900px) {}
Преимущества:
- короче
- читаемее
- лучше сочетается с логическими свойствами
Вложенные контейнеры
Container queries особенно мощны, когда используются вложенно.


В нашем примере не только статьи, но и сама сетка должна реагировать на доступное пространство.
Дополнительный контейнер для layout
<div class="grid-container">
<ul class="grid">
<li class="article-container">...</li>
<li class="article-container">...</li>
<li class="article-container">...</li>
</ul>
</div>
.grid-container {
container: layout / inline-size;
}
Адаптация сетки
.grid {
display: grid;
gap: 1rem;
}
@container layout (inline-size > 800px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
.article-container:first-child {
grid-column: span 2;
}
}
@container layout (inline-size > 1000px) {
.grid {
grid-template-columns: repeat(4, 1fr);
}
.article-container:first-child {
grid-column: span 4;
}
.article-container:nth-child(2),
.article-container:nth-child(3) {
grid-column: span 2;
}
}
Теперь:
- сетка реагирует на доступное пространство
- статьи внутри неё адаптируются независимо
Это и есть component-first подход.
Container units
Container queries дополняются container units — единицами измерения, зависящими от размера контейнера.
Самая полезная из них cqi (Container Query Inline).
article {
padding: 4cqi;
}
Чтобы избежать слишком больших или маленьких значений, используется clamp():
article {
padding: clamp(1rem, 4cqi, 2rem);
}
Таким же образом можно задавать font-size, gap и другие размеры — без дополнительных breakpoint’ов.
Style queries
Container queries позволяют запрашивать не только размер, но и стили элемента.


Например, если нужно выделить «featured»-статьи:
<li class="article-container" style="--featured: true">...</li>
@container style(--featured: true) {
article {
border-radius: 0.2rem;
background: pink;
border: 1px solid deeppink;
padding: clamp(1rem, 5cqi, 3rem);
}
}
📌 Style containment есть у всех элементов по умолчанию — отдельный контейнер объявлять не нужно.
⚠️ На данный момент style queries поддерживаются в Chrome и Edge, но отсутствуют в Safari и Firefox.
Поддержка браузеров и fallback
- Size container queries поддерживаются всеми современными браузерами, что важно учитывать при отладке современных интерфейсов.
- Для старых браузеров существует официальный polyfill от команды Chrome
Это позволяет безопасно использовать container queries уже сейчас.
Нужны ли media queries дальше?
Да — и они никуда не исчезнут.
Media queries по-прежнему нужны для:
- prefers-reduced-motion
- prefers-color-scheme
- особенностей устройства и среды
Но для layout и компонентов container queries со временем станут основным инструментом.
При работе с адаптивными компонентами важно учитывать не только CSS, но и вес визуальных ресурсов. Современные форматы изображений и кодеки напрямую влияют на скорость загрузки и стабильность макета. Если хочешь глубже разобраться в этом, посмотри подробный разбор того, как работают форматы изображений — от пикселей до кодеков.
Итог
CSS Container Queries:
- решают фундаментальную проблему компонентной адаптивности
- позволяют писать более чистый и поддерживаемый CSS
- отлично масштабируются в сложных интерфейсах
Не обязательно переписывать весь проект сразу.
Если есть компонент, который сложно реализовать с media queries — container queries почти наверняка будут лучшим решением.