С помощью медиазапросов можно корректировать макеты в зависимости от размера области просмотра или типа используемого устройства. Запросы контейнеров позволяют вносить более точные изменения в элементы, основываясь на размере и состоянии их предшественников, или контейнеров.
Представьте, что у вас есть форма подписки на рассылку, которая предназначена для использования в нескольких контекстах на вашем сайте. Возможно, вы хотите, чтобы она занимала всю ширину страницы на странице регистрации, но на странице с другим контентом помещалась в отдельный столбец.
Как показано в этой демонстрации, с помощью контейнерных запросов можно настраивать такие свойства, как размер шрифта, отступы и макет элемента, на основе атрибутов его ближайшего контейнера, независимо от размера области просмотра.
Настройка запроса контейнера
В отличие от медиа-запросов, контейнерные запросы состоят из двух частей:
- Дайте определение контейнеру.
- Напишите стили для дочернего элемента, которые будут применяться, когда родительский контейнер соответствует условиям запроса.
Определение контейнера
Вы можете определить контейнер, используя свойство 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
рассчитывается на основе высоты контейнера.