Всё, что нужно знать о CSS Container Queries в 2026 году — от базового синтаксиса до продвинутых паттернов. Практические примеры, реальные сценарии и поддержка браузеров от senior frontend-разработчика с 20-летним опытом.
Если вы когда-нибудь создавали переиспользуемый компонент и боролись за то, чтобы он одинаково хорошо выглядел в разных контекстах — узкой боковой панели, широкой основной колонке или секции на всю ширину — CSS Container Queries это то решение, которого вы ждали.
До появления Container Queries единственным способом сделать компоненты адаптивными были медиа-запросы (@media), которые реагируют на размер окна браузера. Но компоненту всё равно, какой размер у окна — ему важно, сколько места выделил родительский контейнер. Карточка товара в боковой панели шириной 300px и та же карточка в основной колонке шириной 900px должны подстраиваться под своё доступное пространство, а не под окно браузера.
Container Queries решают эту проблему. Они позволяют запрашивать размер родительского контейнера и применять стили к вложенным элементам. Это делает компоненты по-настоящему самодостаточными, переиспользуемыми и контекстно-зависимыми — настоящий сдвиг парадигмы в адаптивной вёрстке.
CSS Container Query — это правило @container,
которое применяет стили на основе размеров именованного контейнера,
а не окна браузера. Чтобы создать контейнер, используется свойство
container-type (или сокращённое container) на
родительском элементе.
Базовая логика проста:
container-type родителю@container (min-width: 400px) для дочерних элементов
Свойство container-type определяет элемент как контейнер для запросов.
Самое частое значение — inline-size, которое отслеживает ширину:
.card-container { container-type: inline-size; }
Контейнеру можно дать имя через container-name. Это необходимо,
когда у вас есть вложенные контейнеры и нужно обратиться к конкретному:
.sidebar { container-type: inline-size; container-name: sidebar; } .main-content { container-type: inline-size; container-name: content; }
Сокращённая запись container объединяет оба свойства:
/* container: <имя> / <тип> */ .card-grid { container: card-grid / inline-size; }
После определения контейнера любой дочерний элемент может использовать
@container:
.card { display: grid; grid-template-columns: 1fr; gap: 1rem; } @container (min-width: 400px) { .card { grid-template-columns: 1fr 1fr; } } @container (min-width: 600px) { .card { grid-template-columns: 1fr 1fr 1fr; } }
Если контейнер именованный, укажите его имя в запросе:
@container sidebar (min-width: 300px) { .widget { font-size: 1.1rem; } }
💡 Лучшая практика: Всегда именуйте контейнеры при вложенности. Безымянные запросы применяются к ближайшему контейнеру-предку, что может дать неожиданные результаты в сложных макетах. Имя делает намерение явным.
Вместе с Container Queries появились единицы измерения контейнера —
относительные единицы длины, работающие как viewport-единицы (vw,
vh), но относительно контейнера.
| Единица | Относительно | Аналог viewport | Применение |
|---|---|---|---|
cqw |
1% ширины контейнера | vw |
Горизонтальные размеры, отступы |
cqh |
1% высоты контейнера | vh |
Вертикальные размеры |
cqi |
1% inline-размера контейнера | vi |
Типографика, отступы (рекомендуется) |
cqb |
1% block-размера контейнера | vb |
Вертикальный ритм, расстояния между блоками |
cqmin |
Меньшее из cqi и cqb |
vmin |
Адаптивные иконки, квадратные элементы |
cqmax |
Большее из cqi и cqb |
vmax |
Полноэкранные наложения внутри контейнера |
Практический пример — плавающая типографика, масштабируемая вместе с контейнером:
.card-title { font-size: clamp(1rem, 4cqi, 2.5rem); padding: 1cqi 2cqi; } .card-image { width: 100%; height: 30cqh; object-fit: cover; }
💡 Совет: Используйте cqi вместо cqw для
адаптивной типографики. cqi учитывает режим письма (inline-ось),
поэтому дизайн работает и в горизонтальных, и в вертикальных языках без изменений.
Container Queries не заменяют медиа-запросы — они их дополняют. Понимание, когда использовать каждый подход — ключ к чистой адаптивной архитектуре.
| Сценарий | Использовать | Почему |
|---|---|---|
| Макет страницы (сетка, колонки, сайдбар) | @media |
Структура страницы должна реагировать на окно |
| Переиспользуемые компоненты (карточки, виджеты, формы) | @container |
Компоненты должны работать в любом контейнере |
| Размер шрифта и отступы | cqi |
Плавное масштабирование без дополнительных запросов |
| Печать, reduced motion, тёмная тема | @media |
Это предпочтения пользователя/браузера, не зависящие от макета |
Создадим реальный компонент — карточку товара, которая адаптируется к трём разным ширинам контейнера без единого медиа-запроса:
/* Определяем контейнер */ .product-grid-cell { container: product-card / inline-size; } /* Базовые стили — для самого узкого контекста */ .product-card { display: flex; flex-direction: column; gap: 0.75rem; padding: 1rem; } .product-card__image { width: 100%; aspect-ratio: 1; object-fit: cover; } .product-card__title { font-size: clamp(0.9rem, 3cqi, 1.4rem); } .product-card__button { display: none; /* Скрыт в узком макете */ } /* Средний контейнер: горизонтальная раскладка */ @container product-card (min-width: 350px) { .product-card { flex-direction: row; align-items: center; } .product-card__image { width: 120px; height: 120px; } } /* Широкий контейнер: показываем кнопку CTA */ @container product-card (min-width: 500px) { .product-card__button { display: inline-flex; } }
Эта карточка отлично работает в боковой панели (вертикальная стопка, без кнопки), в колонке среднего размера (горизонтальный макет) и в основной области (с кнопкой призыва к действию).
Виджеты дашборда — идеальный кейс для Container Queries. Виджет может отображать данные по-разному в одно-, двух- или трёхколоночной сетке:
.dashboard-widget { container: widget / inline-size; } @container widget (max-width: 300px) { .widget-chart { height: 150px; } .widget-legend { display: none; } } @container widget (min-width: 501px) { .widget-chart { height: 350px; } .widget-footer { display: flex; } }
Навигация с Container Queries может переключаться с гамбургера на горизонтальное меню в зависимости от ширины контейнера, а не окна:
.nav-container { container: nav / inline-size; } @container nav (max-width: 400px) { .nav-links-desktop { display: none; } .nav-hamburger { display: block; } } @container nav (min-width: 401px) { .nav-links-desktop { display: flex; } .nav-hamburger { display: none; } }
Самый мощный паттерн: используйте CSS Grid с auto-fill и
minmax для макета страницы, а Container Queries пусть
управляют содержимым каждой ячейки:
.product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.5rem; } .product-grid > * { container: grid-item / inline-size; }
Сетка определяет количество колонок, а каждый элемент сетки использует Container Queries для стилизации содержимого. Ни одного медиа-запроса для компонента — он адаптируется к ширине, которую даёт ему сетка.
По состоянию на май 2026 года CSS Container Queries поддерживаются всеми основными браузерами:
Статус Baseline (широкодоступно) был достигнут в начале 2024 года. Полифиллы не требуются. Единственное исключение — IE11 (менее 0.5% трафика в 2026).
Готовы попробовать Container Queries в своём проекте? Вот минимальный пример:
/* 1. Определяем контейнер */ .responsive-wrapper { container: wrapper / inline-size; } /* 2. Стилизуем дочерние элементы */ .my-component { padding: 1rem; } @container wrapper (min-width: 450px) { .my-component { padding: 2rem; display: grid; grid-template-columns: 1fr 1fr; } }
Всё. Добавьте container родителю, напишите @container
для потомков — и компонент станет контейнерно-зависимым. Браузер делает всё
остальное — никакого JavaScript, ResizeObserver или фреймворк-хаков.
Container Queries — одна из самых impactful возможностей CSS, которую стоит внедрить сегодня. Она фундаментально изменит ваше мышление об адаптивном дизайне — в лучшую сторону.
Нужна помощь с внедрением Container Queries в вашем проекте? Я занимаюсь фронтенд-архитектурой и разработкой. Посмотрите мои услуги или свяжитесь со мной для консультации.
Я создаю production-веб-приложения на современном CSS и JavaScript. Расскажите о задаче — бесплатная консультация.