Container Queries: The End of Media Queries?
Присаживайся, наливай кофе. Сегодня поговорим о вещи, которая прямо сейчас меняет правила игры в адаптивной верстке. Если ты до сих пор верстаешь интерфейсы, опираясь исключительно на ширину экрана пользователя, у меня для тебя новости: мир изменился. На дворе 2026 год, и Container Queries (контейнерные запросы) окончательно вышли из категории «экспериментальная фича» в абсолютный стандарт современной разработки.
Давай честно: Media Queries изначально были компромиссом. Мы пытались адаптировать отдельные независимые компоненты, зная только размер огромного «окна» браузера. Пришло время избавиться от этого костыля.
Как мы страдали раньше
Представь классическую задачу: у тебя есть карточка товара. Она должна идеально смотреться и в боковой панели (шириной 300px), и в основном контенте (шириной 800px), и в трехколоночной сетке на главной странице.
Раньше, чтобы решить эту боль, мы использовали один из трех костылей:
- Миллион CSS-модификаторов. Мы создавали классы вроде
.card--sidebar,.card--grid,.card--featured. В итоге CSS разбухал, а перенос карточки в другое место превращался в увлекательный квест по переписыванию классов в HTML. - JS-слежка за размерами (ResizeObserver). Мы вешали слушатели на каждый элемент, дергали DOM, ловили микрофризы интерфейса и знатно проседали по метрике CLS (Cumulative Layout Shift).
- Попытки выжать всё из гридов. Да, CSS Grid частично спасал ситуацию. Если тебе интересно, как мы пытались выжимать максимум из сеток, зацени наш гайд по Mastering CSS Grid Subgrid, но даже субгриды не спасали, когда карточке банально не хватало физической ширины родительского блока для перестроения контента.
Как делать правильно в 2026 году
Современный подход невероятно элегантен. Мы больше не спрашиваем у браузера: «Эй, какая там ширина у твоего экрана?». Мы спрашиваем у конкретного родительского блока: «Сколько у меня свободного места внутри тебя?».
Для этого мы используем связку из свойства container-type (которое превращает элемент в контекст отслеживания) и директивы @container. Это позволяет создавать по-настоящему изолированные веб-компоненты, которые сами знают, как себя вести в любых условиях.
Конечно, современный CSS предлагает и другие глубокие интеграции — например, инициатива CSS Houdini дает нам кастомные свойства глубоко в движке рендеринга, но Container Queries — это то, что работает прямо здесь и сейчас на уровне чистого CSS, без единой строчки JavaScript.
Готовый сниппет кода
Давай посмотрим на живом примере. Мы объявим родительский контейнер и заставим карточку менять раскладку с вертикальной на горизонтальную, как только ее родитель станет шире 500 пикселей.
<!-- HTML-разметка -->
<div class="product-widget-area">
<div class="card-container">
<article class="product-card">
<div class="product-img"></div>
<div class="product-info">
<h3>Умная колонка нового поколения</h3>
<p>Звук, который заполняет всю комнату. Теперь с поддержкой ИИ.</p>
</div>
</article>
</div>
</div>
<style>
/* 1. Делаем обертку контекстом контейнера */
.card-container {
container-type: inline-size;
container-name: product-card-host;
width: 100%;
}
/* 2. Дефолтные стили для узкого состояния (мобильный вид / сайдбар) */
.product-card {
display: flex;
flex-direction: column;
gap: 16px;
padding: 16px;
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 12px;
}
.product-img {
width: 100%;
aspect-ratio: 16/9;
background: #cbd5e1;
border-radius: 8px;
}
/* 3. Магия: меняем стили в зависимости от ширины КОНТЕЙНЕРА */
@container product-card-host (min-width: 500px) {
.product-card {
flex-direction: row;
align-items: center;
}
.product-img {
width: 180px;
height: 180px;
aspect-ratio: 1;
}
}
</style>
Частая ошибка новичков
Самый частый капкан, в который попадают мидлы при первом знакомстве с Container Queries — это попытка применить стили к самому контейнеру внутри его же медиа-запроса.
Запомни золотое правило: контейнер не может стилизовать сам себя на основе своего размера.
Если ты напишешь что-то вроде:
@container product-card-host (min-width: 500px) {
.card-container {
padding: 40px; /* ТАК ДЕЛАТЬ НЕЛЬЗЯ */
}
}
Браузер просто проигнорирует это правило или сойдет с ума от бесконечного цикла (infinite loop). Изменение размеров самого контейнера меняет условия запроса, что снова меняет размеры контейнера… Ну, ты понял. Внутри @container мы стилизуем только дочерние элементы этого контейнера (в нашем случае — .product-card и её внутренности).
Убивают ли Container Queries привычные Media Queries? Нет. Нам все еще нужны медиа-запросы для глобальных вещей: адаптации шапки, подвала, раскладки крупных секций страницы и отслеживания системных настроек пользователя (вроде prefers-color-scheme). Но для переиспользуемых UI-компонентов эра медиа-запросов официально завершена.
🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!