Контейнерные запросы

Инструмент показывает, чем контейнерный запрос @container отличается от медиазапроса @media. Одна и та же карточка с одинаковым CSS стоит в двух колонках разной ширины: с @container каждая карточка перестраивается по ширине своей колонки, с @media — обе сразу по ширине окна. Можно менять ширины, порог, container-type и container-name, видеть размер единицы cqi и забрать готовый CSS.

Как пользоваться

Кнопка «Развернуть» открывает инструмент на всё окно. Настройки и предпросмотр сохраняются; вернуться можно кнопкой «Свернуть» или клавишей Escape.

Двигайте ползунки колонок A и B: карточка переходит из столбика в две колонки, когда ширина колонки достигает порога. Затем переключитесь на @media и двигайте «Ширину окна» — теперь обе карточки меняются одновременно, а ширина колонок не важна.

Предпросмотр работает в отдельном окне (iframe), поэтому медиазапросы в нём зависят от ползунка, а не от размера вашего браузера. Таблица под ним показывает, что вычислил браузер: ширину контейнера, сработало ли правило, сколько пикселей в 1cqi и размер заголовка.

Запрос

Готовим предпросмотр…

Что сработало в каждой колонке
КолонкаШирина контейнераПравило min-width1cqiРазмер заголовка

CSS

Для интерактивного примера включите JavaScript. Пример CSS контейнерного запроса:

.column {
  container-type: inline-size;
  container-name: card;
}

.card {
  display: grid;
  gap: 12px;
  padding: 16px;
}

.card__title {
  /* 5cqi — 5 % ширины контейнера */
  font-size: clamp(1rem, 5cqi, 1.75rem);
}

@container card (min-width: 400px) {
  .card {
    grid-template-columns: 120px 1fr;
    align-items: center;
  }
}

Зачем нужны контейнерные запросы

Медиазапрос знает только ширину окна. Карточка товара в узкой боковой колонке и в широкой основной на одном и том же экране получает одинаковые стили — и в узкой колонке ей тесно. Контейнерный запрос спрашивает ширину ближайшего родителя-контейнера, поэтому компонент сам подстраивается под место, куда его поставили, — в сетке, боковой панели или модальном окне.

Как объявить контейнер

  • container-type: inline-size — обычный выбор: запросы по ширине. Высота контейнера, как и раньше, зависит от содержимого.
  • container-type: size — запросы и по ширине, и по высоте. Такой контейнер не растягивается по содержимому, поэтому ему нужна явная высота — иначе он схлопнется.
  • container-type: normal — значение по умолчанию: элемент не контейнер для запросов по размеру, @container (min-width: …) его не видит.
  • container-name задаёт имя, чтобы обратиться к нужному контейнеру: @container card (min-width: 400px). Без имени запрос относится к ближайшему предку-контейнеру.
CSS
.column {
  container-type: inline-size;
  container-name: card;
}

@container card (min-width: 400px) {
  .card {
    grid-template-columns: 120px 1fr;
  }
}

Единицы cqi, cqw и другие

1cqi — 1 % ширины контейнера (точнее, его размера по строчной оси), 1cqb — 1 % размера по блочной оси, cqw и cqh — ширины и высоты, cqmin и cqmax — меньшего и большего из них. Заголовок карточки в примере задан как clamp(1rem, 5cqi, 1.75rem): в узкой колонке он мельче, в широкой — крупнее, независимо от окна. Если подходящего контейнера нет, единицы считаются от размера окна.

Вопросы и ответы

Почему @container не срабатывает?

Проверьте, что у родителя задан container-type, а правило применяется к его потомкам: контейнер не может запрашивать собственный размер. Если в запросе указано имя, оно должно совпадать с container-name.

Заменяют ли контейнерные запросы медиазапросы?

Нет, они дополняют друг друга. Раскладку всей страницы — число колонок, видимость боковой панели — удобно задавать медиазапросами, а поведение компонентов внутри колонок — контейнерными.

Поддерживаются ли они браузерами?

Да, запросы по размеру и единицы cq* работают во всех современных браузерах. Если нужно поддержать старые, задайте сначала простую раскладку, а контейнерные запросы используйте как улучшение.

Изучить адаптивную вёрстку

Медиазапросы описаны в статье о правиле @media, общий подход — в уроке об адаптивной вёрстке. Плавные размеры между двумя ширинами строит инструмент «Размер текста».