Контейнерные запросы (Container Queries) — новый стандарт адаптивности вместо медиазапросов?
В мире веб-разработки происходит тихая революция. После десятилетий господства медиазапросов (@media) появляется новый стандарт адаптивного дизайна — контейнерные запросы (@container). Эта технология меняет парадигму адаптивности, позволяя элементам адаптироваться не к размеру экрана, а к размеру их собственного контейнера. Давайте разберёмся, как это работает и когда стоит использовать новый подход.
Что такое контейнерные запросы?
Контейнерные запросы — это CSS-технология, которая позволяет элементам адаптировать свои стили в зависимости от размеров ближайшего контейнера-родителя, а не окна браузера. Это решает одну из главных проблем медиазапросов — их привязку к размерам viewport.
Технология состоит из двух основных частей:
- Определение контейнера с помощью свойства
container-type - Запрос к контейнеру с использованием правила
@container
Базовый пример:
/* 1. Определяем контейнер */
.component-container {
container-type: inline-size;
}
/* 2. Применяем стили в зависимости от размера контейнера */
.component {
display: grid;
grid-template-columns: 1fr;
}
@container (min-width: 500px) {
.component {
grid-template-columns: 1fr 1fr;
}
}
В этом примере компонент изменит свою layout-структуру, когда ширина его контейнера достигнет 500px, независимо от размера всего окна браузера.
Сравнение с медиазапросами
Медиазапросы (@media)
- Ориентированы на размер viewport
- Глобальная область видимости
- Хороши для макета страницы
- Плохо подходят для компонентов
- Не учитывают контекст вложенности
Контейнерные запросы (@container)
- Ориентированы на размер контейнера
- Локальная область видимости
- Идеальны для независимых компонентов
- Учитывают контекст вложенности
- Позволяют создавать truly reusable компоненты
"Контейнерные запросы — это то, о чём мы мечтали последние 10 лет. Они позволяют компонентам быть по-настоящему независимыми от контекста." — Мириам Сюзанна, CSS Working Group
Как использовать контейнерные запросы
1. Определение контейнера
Сначала нужно определить, какой элемент будет контейнером. Для этого используются три основных свойства:
.container {
/* Базовый вариант - отслеживает inline-size (width) */
container-type: inline-size;
/* Для отслеживания и ширины, и высоты */
container-type: size;
/* Можно задать имя контейнера для специфических запросов */
container-name: card-container;
/* Сокращённая запись: имя и тип */
container: card-container / inline-size;
}
2. Создание запросов
После определения контейнера можно писать запросы к его размерам:
@container (min-width: 400px) {
.card {
/* Стили для контейнеров шире 400px */
grid-template-columns: 1fr 2fr;
}
}
/* Запрос к конкретному контейнеру по имени */
@container card-container (max-width: 300px) {
.card {
/* Стили для узких контейнеров */
flex-direction: column;
}
}
3. Единицы измерения cqi и cqb
Для контейнерных запросов введены специальные единицы измерения:
cqi— 1% от inline-размера контейнера (горизонтального в латинских языках)cqb— 1% от block-размера контейнера (вертикального)cqmin— минимальное из cqi и cqbcqmax— максимальное из cqi и cqb
Когда использовать контейнерные запросы?
Идеальные сценарии:
- Компонентные библиотеки — независимые от контекста компоненты
- Сайтбилдеры и CMS — где компоненты могут оказаться в разных областях
- Сложные сетки — когда элементы должны адаптироваться к доступному пространству
- Виджеты и embed-элементы — которые могут быть встроены в разные сайты
- Дизайн-системы — для создания по-настоящему переиспользуемых компонентов
Пример: адаптивная карточка товара
.product-card-container {
container-type: inline-size;
}
.product-card {
display: flex;
flex-direction: column;
gap: 1rem;
}
@container (min-width: 350px) {
.product-card {
flex-direction: row;
}
.product-image {
width: 120px;
}
}
@container (min-width: 600px) {
.product-card {
display: grid;
grid-template-columns: 200px 1fr;
}
.product-title {
font-size: 1.5rem;
}
}
Такой компонент будет корректно отображаться как в узком сайдбаре (200px), так и в широкой основной области (800px), адаптируясь именно к доступному ему пространству, а не к размеру экрана.
Поддержка браузеров и fallback
На момент написания статьи контейнерные запросы поддерживаются:
- Chrome 105+
- Edge 105+
- Safari 16+
- Firefox 110+
Для браузеров без поддержки можно использовать следующие подходы:
1. Использование @supports
/* Базовые стили для всех браузеров */
.card {
display: flex;
flex-direction: column;
}
/* Улучшенные стили для поддерживающих браузеров */
@supports (container-type: inline-size) {
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
flex-direction: row;
}
}
}
2. Полифилы
Существует несколько полифилов, эмулирующих поведение контейнерных запросов:
- Официальный полифил от Chrome Labs
- EQCSS — расширение CSS с элементами контейнерных запросов
Лучшие практики работы с контейнерными запросами
- Начинайте с мобильного вида — проектируйте сначала базовые стили без запросов
- Используйте логические breakpoints — ориентируйтесь на содержание, а не на магические числа
- Комбинируйте с медиазапросами — для глобального layout'а и системных особенностей
- Тестируйте в разных контекстах — вкладывайте компоненты в контейнеры разного размера
- Документируйте контейнерные требования — указывайте минимальные/максимальные размеры для компонентов
Полезные ресурсы
- MDN: Container Queries — официальная документация
- Container Queries для дизайнеров — практическое руководство
- Интерактивная демонстрация — примеры использования
- Полное руководство от Smashing Magazine
Контейнерные запросы не заменяют медиазапросы полностью, но открывают новые возможности для создания по-настоящему адаптивных компонентов. По мере роста поддержки браузерами эта технология станет стандартом в веб-разработке, позволяя создавать более гибкие и независимые UI-компоненты.



