Container Queries: The End of Media Queries?

Эра адаптивности 2.0: Почему Media Queries больше не вывозят?

Присаживайся, наливай кофе. Давай начистоту: сколько раз ты ловил себя на мысли, что адаптивная верстка — это сизифов труд? Ты берешь обычную карточку товара, которая должна идеально смотреться и в боковой панели (шириной 300px), и в трехколоночной сетке, и на всю ширину экрана. Пишешь тонну медиа-запросов, завязанных на ширину экрана (viewport)… И тут дизайнер меняет сетку. Всё летит к чертям, и ты начинаешь переписывать стили заново.

Проблема в том, что обычные медиа-запросы заставляют нас думать масштабами всего экрана. Но компоненту абсолютно плевать на размер экрана смартфона или монитора! Ему важно лишь то, сколько места выделил под него его непосредственный родитель. И вот здесь на сцену выходят Container Queries (контейнерные запросы), которые переворачивают игру с ног на голову.

Как мы страдали раньше (и почему это было больно)

Вспомни, как мы выкручивались еще пару лет назад. У нас было три пути, и все три вели в ад поддержки кода:

  • Множественные модификаторы. Мы плодили классы вроде .card--sidebar, .card--hero, .card--grid. Стоило перенести карточку из одного сайдбара в другой блок, и приходилось лезть в HTML или JS-шаблон и руками менять класс. Никакой автономности.
  • Костыли на JavaScript. Мы подключали тяжелые ResizeObserver, отслеживали размеры контейнера программно, дергали стейт компонента и вешали соответствующие классы на лету. Привет, лишний JS в бандле, микро-фризы при ресайзе страницы и вечная головная боль с серверным рендерингом (SSR).
  • Жесткие рамки сетки. Мы пытались связать все воедино через сложные CSS-сетки. Кстати, если тебе интересна тема гибких раскладок без лишней боли, обязательно почитай статью про Mastering CSS Grid Subgrid — это еще один мощный инструмент, который идеально работает в связке с современными контейнерами.

Как делать правильно в 2026 году: Полная автономность

В 2026 году Container Queries — это уже абсолютный стандарт, поддерживаемый всеми современными браузерами на 100%. Теперь компонент сам решает, как ему выглядеть, исходя из размеров своего родителя. Все, что нам нужно — это объявить родительский элемент «контейнером», а для дочернего написать простые правила.

Если хочешь освежить в памяти базу по этой технологии, загляни в наш подробный разбор Container Queries: The End of Media Queries?, а сейчас давай перейдем к практике и посмотрим, как это выглядит в реальном коде.

Мы используем свойство container-type: inline-size, чтобы сказать браузеру: «Эй, следи за шириной этого элемента!». А затем, вместо привычного @media, мы пишем @container (min-width: ...). Это полностью развязывает нам руки: теперь карточку можно вставить в любое место сайта, и она сама подстроится под окружение.

Готовый сниппет кода: Карточка-хамелеон

Давай посмотрим на живой пример. У нас есть родительский блок-контейнер и карточка внутри него. Обрати внимание, как изящно меняется раскладка без использования JS и глобальных медиа-запросов:

/* 1. Объявляем родительский элемент контекстом контейнера */
.parent-wrapper {
  container-type: inline-size;
  container-name: card-container; /* Имя контейнера для точечного таргетинга */
  width: 100%;
}

/* 2. Базовые стили карточки (для узкого контейнера / mobile-first подход) */
.product-card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1rem;
  background: #f9f9f9;
  border-radius: 8px;
}

.product-card img {
  width: 100%;
  height: auto;
  object-fit: cover;
}

/* 3. Адаптируем карточку под ширину РОДИТЕЛЯ, а не экрана! */
@container card-container (min-width: 500px) {
  .product-card {
    flex-direction: row;
    align-items: center;
  }

  .product-card img {
    width: 150px;
    height: 150px;
  }
}

@container card-container (min-width: 800px) {
  .product-card {
    padding: 2rem;
    background: #eef5ff;
  }
  
  .product-card .title {
    font-size: 1.8rem;
  }
}

Частая ошибка новичков (Осторожно, бесконечный цикл!)

Самая частая грабля, на которую наступают разработчики при первом знакомстве с технологией — это попытка изменить размеры самого контейнера внутри его же запроса. Например:

/* ТАК ДЕЛАТЬ НЕЛЬЗЯ */
@container (min-width: 500px) {
  .parent-wrapper {
    width: 300px; 
  }
}

Браузер видит, что ширина больше 500px, применяет стиль, уменьшает ширину контейнера до 300px… Но теперь ширина меньше 500px, стиль отменяется, ширина снова растет. В итоге браузер попадает в бесконечный цикл рендеринга, интерфейс начинает дико мерцать, а процессор улетает в космос.

Вторая ошибка — путать container-type: size и container-type: inline-size. Если ты укажешь просто size, то браузер будет ожидать, что ты зафиксировал и ширину, и высоту контейнера. Если высота не задана жестко, контейнер сожмется в ноль (высота схлопнется). Поэтому в 95% случаев для верстки гибких компонентов тебе нужен именно inline-size.

Убивают ли Container Queries старые добрые Media Queries? Конечно, нет. Глобальную сетку страницы, шапку и подвал мы по-прежнему верстаем через @media. Но вот внутренности компонентов теперь — строго зона ответственности @container. Это и есть настоящий, чистый компонентный подход в CSS.

🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!

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

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

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