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

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

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

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

Настройка запроса контейнера

В отличие от медиа-запросов, контейнерные запросы состоят из двух частей:

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

Определение контейнера

Вы можете определить контейнер, используя свойство container-type .

.my-container-element {
  container-type: inline-size;
}

container-type inline-size позволяет вам запрашивать встроенную ось контейнера.

Для выполнения запросов как по inline , так и block осям используйте container-type: size .

main,
.my-component {
  container-type: size;
}

Оба значения container-type применяют разные типы ограничения размера. Ограничение Inline-size для элемента предотвращает влияние его потомков на его размер в строке.

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

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

Поскольку его размер не будет зависеть от размера его дочерних элементов (элемента <p> ), контейнер схлопнется, если ему не будет указан явный размер путем установки его размеров (то есть inline-size , block-size , aspect-ratio ) или если его не поместить в макет с явно заданным размером.

Условия запроса контейнера

После создания контейнера можно добавить условие, заключённое в скобки, которое должно выполняться для применения стилей внутри запроса контейнера. Для запросов размера контейнера, основанных на размерах элементов-предков, условие состоит из следующих элементов:

  • размер: width , height , inline-size , block-size , aspect-ratio или orientation ,
  • оператор сравнения (то есть > , < , = , >= ),
  • и значение длины.
.my-container-element {
  container-type: inline-size;
}

@container (inline-size > 30em) {
  .my-child-element {
    /* styles to apply when .my-container-element is wider than 30em */
  }
}

Условия размера объекта также можно записать с двоеточием и одним значением для проверки.

@container (orientation: landscape) {
  /*...*/
}

@container (min-width: 300px) {
  /*...*/
}

Вы также можете объединить несколько условий, используя ключевые слова, такие как and и or , или объединяя несколько условий вместе с помощью операторов.

@container (inline-size > 40em) and (orientation: landscape)  {
  /*...*/
}

@container (height > 25vh) or (orientation: portrait) {
  /*...*/
}

@container ( 10em <= width <= 500px) {
  /*...*/
}

Именование контейнеров

Чтобы выбрать конкретные контейнеры, даже если они не являются ближайшим предком, можно указать их имя с помощью свойства container-name . Затем можно указать имя контейнера, который нужно запросить, прежде чем определять условия.

.sidebar {
  container-name: main-sidebar;
  container-type: inline-size;
}

@container main-sidebar (inline-size > 20em)  {
  .button-group {
    display: flex;
    padding-inline: 1.25em;
  }
}

Именованный контейнер должен быть предком стилизуемых элементов.

Используйте сокращенную запись со свойством container

Свойство container позволяет использовать сокращенный синтаксис для определения контейнера и указания его типа.

.sidebar {
  container: main-sidebar / inline-size;
}

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

Единицы контейнерного запроса

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

Здесь для заполнения кнопки используется единица длины контейнера cqi (1% от встроенного размера контейнера запроса).

.container {
  container: button-container / inline-size;
}

.one {
  inline-size: 30vw;
}

.two {
  inline-size: 50vw;
}

button {
  padding: 2cqi 5cqi;
}

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

Вложенные контейнерные запросы

Вы можете вкладывать контейнерные запросы внутрь селекторов.

.my-element {
  display: grid;
  padding: 1em 2em;

  @container my-container (min-inline-size: 22em) {
    /* styles to apply when element's container is wider than 22em */
  }
}

/* equivalent to */
.my-element {
  display: grid;
  padding: 1em 2em;
}

@container my-container (min-inline-size: 22em) {
  .my-element {
     /* styles to apply when element's is wider than 22em */
  }
}

Или вложите их в другие контейнерные запросы или правила.

@container my-container (min-inline-size: 22em) {
  .my-element {
      /* styles to apply when element's is wider than 22em */
  }
}
@layer base {
  @container my-container (min-inline-size: 22em) {
    .my-element {
    /* styles to apply */
    }
  }
}

Проверьте свое понимание

Какие характеристики размера можно использовать для условий запроса контейнера? (Отметьте все подходящие варианты)

width
Правильный!
block-size
Правильный!
inline-size
Правильный!
viewport-size
Неверно. viewport-size не является допустимой функцией размера для контейнерных запросов.
height
Правильный!

С типом контейнера inline-size можно запросить aspect-ratio контейнера.

Истинный
Неверно. Тип контейнера inline-size не может запрашивать aspect-ratio элемента, поскольку aspect-ratio учитывает block-size или height ).
ЛОЖЬ
Верно! Для запроса соотношения сторон контейнера вам понадобится container-type size , поскольку он учитывает как строчные, так и блочные размеры контейнера.

Если бы вы хотели использовать относительную единицу измерения контейнера, основанную на высоте контейнера, какой из следующих вариантов вы бы выбрали?

cqi
Неверно. cqi основан на логическом размере контейнера.
cqq
Неверно. cqw основан на ширине контейнера.
cqb
Верно! cqb основан на логическом размере блока контейнера.
cqvh
Неверно. cqvh не является допустимой единицей измерения размера CSS.
cqh
Верно! cqh рассчитывается на основе высоты контейнера.