Что такое CSS container queries и чем они отличаются от media queries?
Media queries реагируют на ширину viewport. Container queries — на ширину ближайшего контейнера. Это позволяет компоненту адаптироваться независимо от того, где в макете он находится.
В чём проблема media queries
Media query привязана к размеру viewport. Если карточка в сайдбаре (300 px) и в главной колонке (800 px) должны выглядеть по-разному, media query не поможет — она не знает, насколько широк родительский контейнер. Приходилось передавать CSS-классы через JS или использовать ResizeObserver — оба варианта хрупкие.
Как работают container queries
Элемент-контейнер помечается свойством container-type. Браузер начинает отслеживать его размер. Дочерние элементы могут запрашивать этот размер через @container.
/* 1. Объявляем контейнер */
.card-wrapper {
container-type: inline-size; /* отслеживать ширину */
container-name: card; /* опционально — имя */
}
/* 2. Стили для дочернего элемента в зависимости от ширины контейнера */
@container (min-width: 480px) {
.card {
display: grid;
grid-template-columns: 160px 1fr;
gap: 16px;
}
}
@container (max-width: 479px) {
.card {
display: flex;
flex-direction: column;
}
}
<!-- Сайдбар: контейнер узкий → вертикальная карточка -->
<aside class="card-wrapper">
<div class="card">...</div>
</aside>
<!-- Главная колонка: контейнер широкий → горизонтальная карточка -->
<main class="card-wrapper">
<div class="card">...</div>
</main>
Один и тот же CSS-компонент автоматически адаптируется — без дополнительных классов или JavaScript.
container-type: size vs inline-size
inline-size— отслеживает только ширину. Используется в 99% случаев.size— отслеживает ширину и высоту. Требует, чтобы у контейнера была явная высота, иначе браузер не может её измерить (intrinsic height становится 0).normal— контейнер для style queries, но не для size queries.
Style queries
Помимо размеров, можно делать запросы по значениям CSS-custom-properties контейнера:
@container style(--variant: compact) {
.card__image { display: none; }
}
Style queries поддерживаются в Chrome 111+ / Safari 18+, но пока не в Firefox (статус: в разработке).
Подводные камни
- Элемент не может запрашивать собственный контейнер. Контейнер создаёт новый контекст форматирования: элемент с
container-typeне может сам участвовать в@containerзапросе, который он определяет. Правило всегда применяется к потомкам. - container-type: size ломает intrinsic height. При
sizeбраузер изолирует контейнер по обеим осям — его высота не определяется содержимым. Если не задать явную высоту, контейнер схлопнется в 0. - Производительность при вложенных контейнерах. Каждый уровень
container-typeдобавляет работу браузеру для отслеживания размеров. В длинных списках с контейнерами на каждой карточке это заметно при resize — лучше ставить контейнер как можно выше в дереве. - Нет медиа-условий о типе устройства. Container queries не заменяют media queries полностью:
@media (prefers-color-scheme: dark),@media print, ориентация — это всё viewport/device-level условия. Оба инструмента нужны вместе. - Именование контейнеров — глобальное.
container-nameне имеет scope. Одинаковые имена в разных компонентах конкурируют, а@container cardнайдёт ближайшего предка с именемcard— не обязательно ожидаемый. - Поддержка браузеров. Базовые size container queries поддерживаются с Chrome 105, Safari 16, Firefox 110 (2023). Если нужно поддерживать браузеры до 2023 года — необходим полифилл (
container-query-polyfill) или fallback через media queries. - Инструменты разработчика. DevTools в Chrome/Firefox 2024 показывают контейнеры в Elements-панели, но подсветка не всегда очевидна. При отладке удобно временно добавить
outline: 2px solid redна элемент сcontainer-type, чтобы увидеть реальную ширину контейнера.
Common mistakes
- Смешивать «container queries» с похожим механизмом без критерия выбора.
- Игнорировать риск: неверно оценить границы применения темы «container queries» и получить хрупкое решение.
- Показывать только синтаксис и не объяснять поведение в runtime или сборке.
What the interviewer is testing
- Объясняет адаптация компонента по размеру контейнера, а не только viewport.
- Показывает на примере, как работает: container query работает от query container и позволяет компоненту менять layout в sidebar, card grid или narrow panel без знания общей ширины страницы.
- Называет production-нюанс и граничный случай для темы «container queries».