Эпоха «резинового» ада закончилась
Налей себе кофе покрепче, потому что сегодня мы похороним один из главных костылей веб-разработки последнего десятилетия. Представь классическую боль: ты верстаешь карточку товара. В сетке на главной странице она должна быть вертикальной, в корзине — горизонтальной, а в боковой панели — вообще превращаться в компактный список. Раньше ты строил медиа-запросы под брейкпоинты экрана. Но что, если экран огромный, а карточка зажата в узком сайдбаре? Медиа-запрос кричит: «У нас 1920px, давай шикарную широкую раскладку!», а по факту карточка сжимается в 300px и превращается в визуальную кашу.
Именно эту проблему решают Container Queries (контейнерные запросы). Они позволяют элементу адаптироваться не к ширине экрана (viewport), а к физическому размеру своего родителя. Давай разберем, почему это полностью меняет правила игры в 2026 году и как внедрить их в свои проекты уже сегодня.
Как мы страдали раньше
До прихода контейнерных запросов наша жизнь состояла из компромиссов, боли и написания тонн лишнего кода. Чтобы заставить один и тот же компонент выглядеть по-разному в зависимости от окружения, мы использовали три основных костыля:
- Умножение классов (БЭМ-модификаторы): Мы плодили классы вроде
.card--sidebar,.card--grid,.card--hero. Это приводило к тому, что разметка становилась грязной, а стили раздувались. Компонент переставал быть по-настоящему независимым. - Тяжелую артиллерию на JavaScript: Мы подключали
ResizeObserver. JS следил за размерами элементов, дергал DOM, вешал классы на лету. Привет, микрофризы при ресайзе, ухудшение перформанса и дерганая анимация. - Сложную математику: Мы пытались выжать максимум из формул. Кстати, если хочешь вспомнить, как мы выкручивались, почитай про математические функции в CSS, где функции
clamp()иcalc()творили чудеса адаптивности, но даже они не могли кардинально перестроить структуру компонента внутри узкого родителя.
Как делать правильно в 2026 году
Сегодня Container Queries поддерживаются всеми современными браузерами и стали стандартом де-факто. Философия проста: мы объявляем родительский элемент «контейнером», а дочерние элементы стилизуем в зависимости от его размеров.
Для этого используется свойство container-type со значением inline-size (чтобы следить за шириной) или size (за шириной и высотой одновременно). А в самом запросе мы пишем @container вместо привычного @media.
Этот подход идеально раскрывается при создании сложных макетов. Например, когда ты сочетаешь контейнерные запросы и продвинутые сетки. Обязательно загляни в руководство по Mastering CSS Grid Subgrid, чтобы понять, как создавать идеальное выравнивание внутренних элементов в таких динамических карточках.
Готовый сниппет кода
Давай посмотрим на живой пример. У нас есть родительский блок-контейнер и карточка внутри него. Обрати внимание на лаконичность современного синтаксиса диапазонов (например, width > 400px), который пришел на смену громоздким min-width.
/* 1. Объявляем родительский элемент контейнером */
.card-wrapper {
container-type: inline-size;
container-name: card-container; /* Имя необязательно, но полезно для вложенности */
width: 100%;
}
/* 2. Базовые стили карточки (для узкого контейнера < 400px) */
.product-card {
display: flex;
flex-direction: column;
gap: 16px;
padding: 16px;
background: #ffffff;
border-radius: 12px;
border: 1px solid #e2e8f0;
}
.product-card__image {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
border-radius: 8px;
}
/* 3. Магия: если контейнер шире 400px, делаем карточку горизонтальной */
@container card-container (width > 400px) {
.product-card {
flex-direction: row;
align-items: center;
}
.product-card__image {
width: 150px;
height: 150px;
aspect-ratio: 1 / 1;
}
}
/* 4. Если контейнер очень широкий (> 700px), увеличиваем акценты */
@container card-container (width > 700px) {
.product-card {
padding: 32px;
gap: 24px;
}
.product-card__title {
font-size: 2rem;
}
}
Частая ошибка новичков
Самый частый капкан, в который попадают разработчики при первой попытке внедрить контейнерные запросы, — это попытка изменить стили самого контейнера внутри его собственного запроса. Например, написать что-то вроде:
@container (width > 500px) { .card-wrapper { padding: 40px; } }
Браузер моментально заблокирует такое поведение. Почему? Потому что это вызывает бесконечный цикл рендеринга (infinite loop). Посуди сам: если увеличение padding у родителя изменит его внутреннюю ширину, это может отменить условие контейнерного запроса. Браузер вернет старые стили, условие снова выполнится… и так по кругу. Запомни железное правило: мы опрашиваем контейнер, но стилизуем только его потомков.
И да, отвечая на вопрос в заголовке: убили ли Container Queries старые добрые Media Queries? Нет. Медиа-запросы все еще идеальны для глобальной сетки страницы, темизации (темная/светлая тема) и системных настроек. Но для верстки независимых UI-компонентов медиа-запросы официально мертвы. Пересаживайся на контейнеры уже сегодня!
🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!