Container Queries: Конец эпохи Media Queries?
Присаживайся, наливай кофе. Сегодня поговорим о технологии, которая прямо сейчас меняет правила игры в компонентном подходе. Ты наверняка помнишь это классическое чувство безысходности, когда дизайнер приносит макет шикарной карточки. Она должна идеально смотреться и в узком боковом сайдбаре, и в широком контентном блоке по центру, и в мобильной сетке в одну колонку.
Раньше мы сразу начинали мысленно плодить сущности: писать кучу модификаторов, подключать JS-скрипты или завязываться на ширину экрана. Но компоненту плевать на ширину экрана! Ему важно лишь то, сколько места выделил под него родительский контейнер. Именно эту фундаментальную боль и решают контейнерные запросы (Container Queries).
Как мы страдали раньше
До появления этого стандарта жизнь фронтендера была полна боли и костылей. Чтобы заставить один и тот же компонент выглядеть по-разному в разных частях страницы, мы использовали три основных пути, и каждый из них был по-своему ужасен:
- Грязные медиа-запросы. Мы писали жесткие конструкции вроде
@media (max-width: 1024px) { .sidebar .card { ... } }. Стоило изменить структуру страницы или перенести сайдбар в другую часть макета, как вся эта хрупкая конструкция рассыпалась на глазах. - Спагетти из классов. Мы заставляли бэкенд или шаблонизатор навешивать классы вроде
card--sidebarилиcard--grid. Это ломало концепцию независимых UI-компонентов. - Слежка через JavaScript. Когда CSS сдавался, мы подключали тяжелую артиллерию в виде
ResizeObserver. Мы отслеживали размеры элемента в рантайме, плодили лишние перерисовки (reflow) и забивали память.
Если ты хочешь глубже погрузиться в историю этой проблемы и посмотреть, как развивалась спецификация, почитай нашу подробную статью Container Queries: The End of Media Queries?, где мы разбирали первые шаги этой технологии.
Как делать правильно в 2026 году
В 2026 году контейнерные запросы стали полноценным золотым стандартом верстки. Поддержка в браузерах давно перевалила за 95%, так что использовать их можно и нужно без всяких опасений.
Идея безумно проста и элегантна. Сначала мы объявляем родительский элемент «контейнером», за размерами которого нужно следить. Для этого используется свойство container-type. Затем внутри этого контекста мы можем использовать директиву @container, которая работает точно так же, как привычный @media, но оценивает ширину не всего окна браузера, а именно нашего родителя.
Кстати, в связке с контейнерными запросами невероятно круто раскрывается современная сеточная раскладка, о которой мы подробно писали в руководстве Mastering CSS Grid Subgrid. Эти две технологии буквально созданы друг для друга.
Готовый сниппет кода
Давай закодим классический пример: карточка, которая автоматически перестраивается из вертикальной в горизонтальную, если ее родитель становится шире 500 пикселей. Обрати внимание, что стили самой карточки полностью изолированы от глобального вьюпорта.
<!-- HTML структура -->
<div class="card-wrapper">
<article class="product-card">
<img src="product.jpg" alt="Товар" class="product-card__image" />
<div class="product-card__content">
<h3>Крутой девайс</h3>
<p>Этот девайс изменит вашу жизнь раз и навсегда.</p>
</div>
</article>
</div>
<style>
/* 1. Объявляем родительский контейнер */
.card-wrapper {
container-type: inline-size;
container-name: card-container;
width: 100%;
}
/* 2. Базовые стили (для узкого пространства) */
.product-card {
display: flex;
flex-direction: column;
gap: 16px;
background: #f5f5f5;
border-radius: 12px;
padding: 16px;
}
.product-card__image {
width: 100%;
height: 200px;
object-fit: cover;
border-radius: 8px;
}
/* 3. Магия: меняем раскладку, если родитель шире 500px */
@container card-container (min-width: 500px) {
.product-card {
flex-direction: row;
align-items: center;
}
.product-card__image {
width: 150px;
height: 150px;
}
}
</style>
Частая ошибка новичков: попытка укусить себя за хвост
Самый частый факап, который я вижу на код-ревью у ребят, только начинающих работать с Container Queries — это попытка применить container-type и @container к одному и тому же элементу.
Запомни железное правило: элемент не может оценивать свои собственные размеры для изменения своих же стилей. Если бы браузер позволял это делать, мы бы легко уходили в бесконечный цикл рендеринга. Представь: элемент видит, что он шире 500px, применяет к себе стиль, который уменьшает его ширину до 400px. Браузер пересчитывает стили, видит, что ширина меньше 500px, отменяет это правило… И так до бесконечности, пока у пользователя не закипит процессор.
Поэтому мы всегда вешаем container-type: inline-size на обертку (предка), а правила внутри @container применяем к дочерним элементам. Только так и никак иначе.
Media Queries, конечно, не умрут окончательно — они по-прежнему нужны для глобальных вещей: темизации (dark mode), детекции тач-экранов или базовой раскладки всей страницы. Но для создания действительно независимых, переиспользуемых микро-фронтендов и UI-китов Container Queries — это абсолютный и бесповоротный мастхэв.
🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!