Container queries (контейнерные запросы) позволяют управлять стилем элементов внутри родительского контейнера, а не только через глобальные медиа-запросы. Это решает задачу адаптации виджетов в разных колонках: элемент может менять размер и расположение в зависимости от ширины своего родителя, будь то узкая колонка в сетке или широкий блок.
1. Подготовка структуры и выбор подхода
Прежде чем писать код, определите, какой виджет вы адаптируете. Это может быть блок с карточками товаров, список услуг или форма обратной связи.
Проверьте текущую структуру HTML. Убедитесь, что у родительского блока есть уникальный класс (например, .widget-grid).
Оцените ограничения: контейнерные запросы поддерживаются современными браузерами (Chrome 123+, Safari 17+). Если нужно поддерживать старые браузеры, используйте фоллбэк через @media или CSS-переменные.
Учтите коммерческую задачу: виджет должен быть функциональным в любой колонке. Не жертвуйте удобством ради экспериментов с дизайном.
2. Настройка контейнера и базовых стилей
Добавьте свойство container: inline; или container: inline-size; к родительскому элементу в CSS.
Пример:
.widget-grid {
display: grid;
container-type: inline-size;
gap: 20px;
}
Здесь container-type: inline-size; означает, что ширина контейнера определяется шириной контента внутри него, а не отступами. Это важно для точных расчётов.
Если используется flexbox, добавьте container-type: inline-size; к родителю flex-контейнера.
3. Применение стилей через @container
Используйте псевдокласс @container внутри селектора родителя.
Пример для виджета с карточками:
.widget-grid {
container-type: inline-size;
}
.widget-grid > .card {
/* Базовые стили */
width: 100%;
padding: 16px;
}
@container (min-width: 400px) {
.widget-grid > .card {
width: calc(50% — 10px);
margin-bottom: 0;
}
}
В этом примере карточки занимают всю ширину в узких колонках (<400px), а при достижении 400px делятся на две колонки.
Можно использовать @container (min-width: 600px) для трёхколоночной сетки.
4. Работа с вложенными контейнерами
Если виджет содержит несколько уровней иерархии, применяйте @container на каждом уровне.
Пример:
.outer-widget {
container-type: inline-size;
}
@container (min-width: 800px) {
.inner-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}
Это позволяет создавать сложные адаптивные структуры без использования @media.
Ограничение: вложенные контейнеры работают только если родительский элемент имеет container-type.
5. Оценка результата и тестирование
Проверьте виджет в разных браузерах: Chrome, Safari, Firefox (с флагом поддержки).
Используйте инструменты разработчика для изменения ширины контейнера вручную.
Убедитесь, что функциональность виджета не нарушается при смене размера колонки.
Проверьте производительность: избыточное использование @container может увеличить размер CSS-файла.
6. Ошибки и ограничения
Ошибка 1: Забыли добавить container-type. Без этого свойства @container не сработает.
Ошибка 2: Использование @container в элементах без display: block/flex/grid. Контейнерные запросы работают только для блочных элементов.
Ограничение: Некоторые браузеры пока не поддерживают контейнерные запросы. Добавьте фоллбэк через @media для старых версий.
Ошибка 3: Неправильный расчёт отступов. Если у контейнера есть padding, он влияет на ширину контента внутри.
7. Практический пример с виджетом услуг
Условный пример: виджет с тремя карточками услуг.
В узкой колонке (до 600px) карточки выстраиваются в одну колонку.
При ширине от 600px до 1200px — две колонки.
При ширине более 1200px — три колонки.
Код:
.services-widget {
container-type: inline-size;
}
.services-widget > .service-card {
width: 100%;
margin-bottom: 20px;
}
@container (min-width: 600px) {
.services-widget > .service-card {
width: calc(50% — 10px);
margin-bottom: 0;
}
}
@container (min-width: 1200px) {
.services-widget > .service-card {
width: calc(33.333% — 6.666px);
margin-bottom: 0;
}
}
Этот подход позволяет одному и тому же контенту корректно отображаться в разных колонках без дублирования кода.
Вопросы и ответы
Можно ли использовать container queries вместе с @media?
Да, это распространённая практика. @container отвечает за адаптацию внутри компонента, а @media — за глобальную адаптацию страницы.
Как проверить поддержку контейнерных запросов в браузере?
Используйте CSS-свойство container-type: inline-size; и проверьте, применяются ли стили внутри @container. В старых браузерах они будут игнорироваться.
Нужно ли переписывать весь код с @media на @container?
Нет. Используйте @container там, где это уместно (локальная адаптация), а @media оставьте для глобальных изменений.
.widget-grid {
display: grid;
container-type: inline-size;
gap: 20px;
}
.widget-grid > .card {
width: 100%;
padding: 16px;
}
@container (min-width: 400px) {
.widget-grid > .card {
width: calc(50% - 10px);
margin-bottom: 0;
}
}


