Container Queries: The End of Media Queries?

Эпоха «резинового» ада закончилась

Налей себе кофе покрепче, потому что сегодня мы похороним один из главных костылей веб-разработки последнего десятилетия. Представь классическую боль: ты верстаешь карточку товара. В сетке на главной странице она должна быть вертикальной, в корзине — горизонтальной, а в боковой панели — вообще превращаться в компактный список. Раньше ты строил медиа-запросы под брейкпоинты экрана. Но что, если экран огромный, а карточка зажата в узком сайдбаре? Медиа-запрос кричит: «У нас 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-канале. Подписывайтесь, чтобы не пропустить!

🚀 Прокачай свой код

Готовые CSS-сниппеты, разбор продвинутых фишек и эксклюзивные материалы — в нашем Telegram-канале.

Подписаться
error: Content is protected !!
Прокрутить вверх