Однажды было время, когда разработка сайтов имела довольно скудный функционал. Кроме того, как посмотреть любимый интернет-ресурс на экране компьютера, обычный пользователь и думать не мог о том, что скоро интернет будет доступен везде. Появились смартфоны, планшеты, ноутбуки, предоставляющие свой индивидуальный размер окна. Возникла необходимость что-то делать с отображением сайтов на каждом из устройств.

В 2010 году была создана концепция адаптивного дизайна. Она заключалась в том, что сайт и его внешний вид должны реагировать на поведение пользователя и окружающую среду его устройства, включая размер экрана и ориентацию. Так появились медиа-запросы (CSS Media Queries), которые и по сей день позволяют отрисовывать страницы в зависимости от указанных свойств и правил.

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

Что такое CSS Container Queries

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

Это нам позволяет более гибко соблюдать модульность элементов: где бы они не были размещены на странице, они будут адаптироваться в зависимости от их контейнеров.

Синтаксис контейнерного запроса очень похож на медиа-запрос:

@container (min-width: 500px) {  /* или любой другой брейкпоинт */
  .box {
    /* стили для адаптации элемента */
  }
}

С чего начинать при работе с CSS Container Queries

Самое важное, что нужно знать о контейнерных запросах, это то, что запрашиваемым элементом в правиле является контейнер, а адаптационные свойства мы пишем для элемента внутри. Для этого нужно точно определить и указать, что для вашего выражения будет являться контейнером, а далее уже писать правила.

Также стоит понимать, что указывание конкретных элементов для контейнерных запросов необходимо для оптимизации производительности браузера. Повторная отрисовка в этом случае будет применена только к выбранным объектам, а не ко всему сайту.

Свойство container-type

Это свойство назначает элементу роль контейнера. Значение этого свойства определяет, относительно изменения какого свойства контейнера будет меняться внутренний элемент.

.box-container
  container-type: inline-size;
}

Свойство container-type может принимать следующие значения:

  • inline-size: создает контейнер, запросы к которому будут учитывать его длину;
  • size: создает контейнер, запросы к которому будут учитывать его длину и высоту;
  • normal: значение по-умолчанию, элемент не будет контейнером.

Пример использования этого свойства в связке с адаптацией внутреннего элемента:

.box-container
  container-type: inline-size;
}

@container (max-width: 768px) {
  .box-item {
    display: flex;
    font-size: 16px;
  }
}

Данная запись говорит о том, что элементу .box-container с помощью свойства container-type мы указали быть контейнером для использования его в контейнерных запросах дочерних элементов. В качестве значения свойства указали inline-size - значит в контейнером запросе будем опираться исключительно на его ширину. Ниже написан уже сам контейнерный запрос для дочернего элемента .box-item. Браузером эти свойства считываются так: как только ширина элемента .box-container будет <= 768px, примени для элемента .box-item внутри него свойства display:flex; и font-size: 16px;.

Свойство container-name

Это свойство указывает имя контейнеру. Используется для случаев, если внутренний элемент адаптируется относительно нескольких контейнеров.

.box-container
  container-name: box;  /* имя может быть задано любое */
}

@container box (min-width: 768px) {
  .box-item {
    display: flex;
    font-size: 24px;
  }
}

Свойство container

Это свойство является сокращенным объединяющим вариантом для свойств container-name и container-type, которые должны быть указаны через знак /.

.box-container
  container: box / size;
}

@container box (max-width: 300px) {
  .box-item {
    display: flex;
    font-size: 14px;
  }
}

Какие проблемы решают CSS Container Queries

Контейнерные запросы помогают найти уникальные решения для крупномасштабных проектов, в которых повторно используются компоненты, содержащиеся в разных частях веб-страниц. Поскольку запросы позволяют компонентам изменять свой внешний вид в соответствии с контекстом, в который они помещены, компоненты становятся многоразовыми и гибкими.

Взгляните на пример ниже. В нем продемонстрировано использование контейнерных запросов. Чтобы понять наглядней их работу, поменяйте ширину окошка браузера, чтобы ширина блока с примером также изменилась.

Как видим, в примере использована одна и та же карточка (с заголовком, картинкой и описанием), которая помещена в широкий блок main и узкий блок aside. Им мы указали быть контейнерами с помощью свойства container-type: inline-size;. Далее в контейнерном запросе мы говорим браузеру, что если контейнер будет более 500px шириной, то поменяй нам вид карточки (картинка слева, а заголовок с описанием справа) с дефолтного (все элементы друг под другом). При изменении окна области примера будем наблюдать соответствующие виды карточек.

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

Когда использовать Container Queries и когда Media Queries

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

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

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

Контейнерные запросы лучше использовать для многоиспользуемых компонентов и для элементов, точно зависящих от их родителей.

Поддержка Container Queries

На данный момент контейнерные запросы по умолчанию включены в Chrome и последние версии популярных браузеров.

Поддержка браузерами
chrome
Chrome
106
firefox
Firefox
110
internet explorer
IE
 
edge
Edge
106
safari
Safari
16
opera
Opera
94