CSS Container Queries: как забыть про Media Queries в 2026 году
Присаживайся, коллега. Давай честно: сколько раз ты проклинал Media Queries, когда пытался впихнуть одну и ту же карточку товара и в узкий сайдбар, и в широкую центральную колонку? Раньше нам приходилось плодить десятки модификаторов в духе card--sidebar или card--small, просто чтобы компонент не развалился. Но на дворе 2026 год, и если ты до сих пор завязываешь адаптивность компонента на ширину окна браузера, у меня для тебя новости — мы так больше не делаем.
Сегодня настоящий стандарт индустрии — это Container Queries. Это когда компоненту глубоко плевать на размер вьюпорта, он смотрит только на то, сколько места выделил ему родитель. Это фундаментальный сдвиг в мышлении, который наконец-то делает компонентный подход по-настоящему независимым.
Как мы страдали раньше
Вспомни этот ад: ты создаешь идеальный интерфейс, и тут прилетает правка — «давайте добавим правую панель». И всё, твоя сетка едет, потому что медиа-запросы срабатывают на 1200px ширины экрана, но контентная область теперь стала меньше на 300px. Чтобы это работало, нам приходилось выстраивать сложнейшие каскады и жестко связывать стили компонентов с контекстом их размещения.
Мы пытались лечить это через грамотную архитектуру CSS, используя методологии вроде BEM, но проблема оставалась на уровне самой технологии. Media Queries были инструментом для страниц, а не для компонентов. Мы городили JS-костыли с ResizeObserver, которые тормозили рендеринг и заставляли браузер потеть. Забудь об этом как о страшном сне.
Как делать правильно в 2026 году
Теперь всё решается парой строк кода. Логика простая: мы объявляем родительский элемент «контейнером», а дочерние элементы начинают слушать его размеры. Это позволяет верстать микро-лейауты, которые адаптируются под любое свободное пространство автоматически.
Основная фишка в свойстве container-type: inline-size. Оно говорит браузеру: «Следи за шириной этого блока». А дальше мы используем магическое правило @container. Кстати, если у тебя что-то идет не так при верстке сложных сеток, не забудь заглянуть в статью о том, как дебажить CSS Grid и Flexbox — в 2026-м инструменты разработчика стали еще круче и отлично показывают границы контейнеров.
Готовый сниппет кода
Давай посмотрим на живом примере. У нас есть карточка, которая должна менять раскладку с вертикальной на горизонтальную, если для нее достаточно места.
/* 1. Определяем контейнер для карточки */
.card-wrapper {
container-type: inline-size;
container-name: post-card;
width: 100%;
}
/* 2. Базовые стили карточки (мобильный вид по умолчанию) */
.card {
display: flex;
flex-direction: column;
gap: 16px;
padding: 20px;
background: #f4f4f4;
border-radius: 12px;
}
/* 3. Магия: если контейнер шире 450px, меняем раскладку */
@container post-card (min-width: 450px) {
.card {
flex-direction: row;
align-items: center;
}
.card__image {
width: 150px;
height: 150px;
}
}
/* Можно использовать даже относительные единицы контейнера! */
.card__title {
font-size: clamp(1rem, 5cqw, 2rem);
}
Частая ошибка новичков
Самый частый факап, который я вижу на ревью у мидлов — это попытка повесить @container на тот же самый элемент, который является контейнером. Запомни: элемент не может опрашивать свои собственные размеры.
Если ты пропишешь container-type для блока .card и внутри этого же блока попытаешься использовать @container для изменения его свойств (например, background), это не сработает или вызовет бесконечный цикл пересчета. Всегда нужна обертка (wrapper), которая будет выступать в роли «измерителя», либо опрашивай ближайшего подходящего родителя. И не забывай про container-name, если у тебя на странице много вложенных контейнеров — это сэкономит тебе кучу нервов при отладке.
🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!