Правило at `@container` CSS
Базовая поддержка Широко доступно
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и во многих версиях браузеров. Она доступна во всех браузерах с февраля 2023 года.
@container — это CSS условное групповое at-правило, которое применяет стили к контексту изоляции. Объявления стилей фильтруются по условию и применяются к элементам внутри контейнера, если условие истинно. Условие проверяется при изменении размера запрашиваемого контейнера, <style-feature> или состояния прокрутки.
Условие должно указывать container-name, <container-query> или оба параметра.
Свойство container-name задаёт список имён контейнеров запросов, используемых для фильтрации контейнеров, к которым применяются правила @container. Если указано только значение container-name (запрос контейнера только по имени), содержащиеся в нём правила применяются ко всем контейнерам, у которых задано одно или несколько значений container-name.
Характеристики контейнера в <container-query> проверяются для выбранных контейнеров. Если <container-name> не указано, характеристики <container-query> проверяются для ближайшего родительского контейнера запросов, у которого совпадает значение container-type.
Синтаксис
/* With a <size-query> */
@container (width > 400px) {
h2 {
font-size: 1.5em;
}
}
/* With an optional <container-name> */
@container tall (height > 30rem) {
p {
line-height: 1.6;
}
}
/* With a <container-name> only (query is optional) */
@container sidebar {
h2 {
background: blue;
}
}
/* With a <scroll-state> */
@container scroll-state(scrollable: top) {
.back-to-top-link {
visibility: visible;
}
}
/* With an anchored query */
@container anchored(fallback: bottom) {
.infobox::before {
content: "▲";
bottom: 100%;
top: auto;
}
}
/* With a <container-name> and a <scroll-state> */
@container sticky-heading scroll-state(stuck: top) {
h2 {
background: purple;
color: white;
}
}
/* Multiple queries in a single condition */
@container (width > 400px) and style(--responsive: true) {
h2 {
font-size: 1.5em;
}
}
/* Condition list */
@container card (width > 400px), style(--responsive: true), scroll-state(stuck: top) {
h2 {
font-size: 1.5em;
}
}
/* Boolean style() queries */
@container style(--theme: one) or style(--theme: two) {
/* matched container styles */
}
@container style((--theme: one) or (--theme: two)) {
/* matched container styles */
}
@container style(--theme: one) and style(--theme: two) {
/* matched container styles */
}
@container style((--theme: one) and (--theme: two)) {
/* matched container styles */
}
@container not style(--theme: one) {
/* matched container styles */
}
/* range style() queries */
@container style(--number > 4) {
/* matched container styles */
}
Параметры
-
<container-condition> - Один или оба параметра:
<container-name>и<container-query>. Стили, заданные в<stylesheet>, применяются, если условиеtrue.-
<container-name>Необязательно - Имя контейнера для запроса; указывается как
<ident>. Если запрос возвращаетtrue, объявленные стили применяются к дочерним элементам контейнера. -
<container-query>Необязательно - Набор характеристик, проверяемых для контейнера запросов при изменении его размера,
<style-feature>, состояния прокрутки или применённого резервного варианта position-try.
-
Логические ключевые слова в запросах контейнера
Для задания условия контейнера можно использовать логические ключевые слова:
-
andобъединяет два или более условия. -
orобъединяет два или более условия. -
notотрицает условие. В одном запросе контейнера разрешено только одно условиеnot; его нельзя использовать с ключевыми словамиandилиor.
@container (width > 400px) and (height > 400px) {
/* <stylesheet> */
}
@container (width > 400px) or (height > 400px) {
/* <stylesheet> */
}
@container not (width < 400px) {
/* <stylesheet> */
}
Именованные контексты изоляции
Контексту изоляции можно задать имя с помощью свойства container-name.
.post {
container-name: sidebar;
container-type: inline-size;
}
Сокращённая форма записи использует свойство container в виде container: <name> / <type>, например:
.post {
container: sidebar / inline-size;
}
В запросах контейнера свойство container-name используется для отбора контейнеров с совпадающим именем контейнера запросов:
@container sidebar (width > 400px) {
/* <stylesheet> */
}
Сведения об использовании и ограничениях на именование приведены на странице container-name.
Дескрипторы
Запросы <container-condition> включают дескрипторы контейнеров размера, состояния прокрутки и привязки.
Дескрипторы размера контейнера
<container-condition> может включать один или несколько логических запросов размера, каждый из которых заключается в круглые скобки. Запрос размера включает дескриптор размера, значение и — в зависимости от дескриптора — оператор сравнения. В запросах всегда измеряется область содержимого. Синтаксис для нескольких условий такой же, как и для запросов характеристик размера в @media.
@container (min-width: 400px) {
/* … */
}
@container (orientation: landscape) and (width > 400px) {
/* … */
}
@container (15em <= block-size <= 30em) {
/* … */
}
-
aspect-ratio aspect-ratioконтейнера, вычисленное как отношение ширины контейнера к его высоте и выраженное значением<ratio>.-
block-size block-sizeконтейнера, выраженный значением<length>.-
height - Высота контейнера, выраженная значением
<length>. -
inline-size inline-sizeконтейнера, выраженный значением<length>.-
orientation - Ориентация контейнера:
landscapeилиportrait. -
width - Ширина контейнера, выраженная значением
<length>.
Дескрипторы состояния прокрутки контейнера
Дескрипторы состояния прокрутки контейнера указываются внутри <container-condition> в качестве аргумента функции scroll-state(), например:
@container scroll-state(scrollable: top) {
/* … */
}
@container scroll-state(scrolled: block-end) {
/* … */
}
@container scroll-state(stuck: inline-end) {
/* … */
}
@container scroll-state(snapped: both) {
/* … */
}
Поддерживаемые ключевые слова дескрипторов состояния прокрутки контейнера включают физические и относительные к потоку значения.
-
scrollable - Проверяет, можно ли прокручивать контейнер в заданном направлении действиями пользователя, например перетаскиванием полосы прокрутки или жестом на трекпаде. Иными словами, есть ли в заданном направлении содержимое, выходящее за границы контейнера, до которого можно прокрутить? Допустимые значения
scrollableвключают следующие ключевые слова:-
none - Контейнер не является контейнером прокрутки или не может прокручиваться ни в одном направлении.
-
top - Контейнер можно прокручивать к верхнему краю.
-
right - Контейнер можно прокручивать к правому краю.
-
bottom - Контейнер можно прокручивать к нижнему краю.
-
left - Контейнер можно прокручивать к левому краю.
-
x - Контейнер можно прокручивать по горизонтали к левому и/или правому краю.
-
y - Контейнер можно прокручивать по вертикали к верхнему и/или нижнему краю.
-
block-start - Контейнер можно прокручивать к началу блочной оси.
-
block-end - Контейнер можно прокручивать к концу блочной оси.
-
inline-start - Контейнер можно прокручивать к началу строчной оси.
-
inline-end - Контейнер можно прокручивать к концу строчной оси.
-
block - Контейнер можно прокручивать в блочном направлении к началу и/или концу блочной оси.
-
inline - Контейнер можно прокручивать в строчном направлении к началу и/или концу строчной оси.
Если проверка проходит, правила внутри блока
@containerприменяются к потомкам контейнера прокрутки.Чтобы проверить, можно ли прокручивать контейнер, не учитывая направление, используйте значение
noneс операторомnot:@container not scroll-state(scrollable: none) { /* … */ } -
-
scrolled - Проверяет, в каком направлении контейнер прокручивали последним. Допустимые значения
scrolledвключают следующие ключевые слова:-
none - Контейнер не является контейнером прокрутки или ранее не прокручивался ни в одном направлении.
-
top - Последний раз контейнер прокручивали к верхнему краю.
-
right - Последний раз контейнер прокручивали к правому краю.
-
bottom - Последний раз контейнер прокручивали к нижнему краю.
-
left - Последний раз контейнер прокручивали к левому краю.
-
x - Последний раз контейнер прокручивали к левому или правому краю.
-
y - Последний раз контейнер прокручивали к верхнему или нижнему краю.
-
block-start - Последний раз контейнер прокручивали к началу блочной оси.
-
block-end - Последний раз контейнер прокручивали к концу блочной оси.
-
inline-start - Последний раз контейнер прокручивали к началу строчной оси.
-
inline-end - Последний раз контейнер прокручивали к концу строчной оси.
-
block - Последний раз контейнер прокручивали к началу или концу блочной оси.
-
inline - Последний раз контейнер прокручивали к началу или концу строчной оси.
Если проверка возвращает true, правила внутри блока
@containerприменяются к потомкам контейнера прокрутки.Чтобы проверить, прокручивали ли контейнер недавно, не учитывая направление, используйте значение
noneс операторомnot:@container not scroll-state(scrolled: none) { /* … */ } -
-
snapped - Проверяет, будет ли контейнер привязан к родительскому контейнеру привязки прокрутки по заданной оси. Допустимые значения
snappedвключают следующие ключевые слова:-
none - Контейнер не является целью привязки для родительского контейнера прокрутки. При реализации запроса
snapped: noneконтейнеры, которые являются целями привязки для контейнера прокрутки, не получат стили@container, тогда как контейнеры, не являющиеся целями привязки, получат эти стили. -
x - Контейнер является целью горизонтальной привязки прокрутки для родительского контейнера прокрутки, то есть привязывается к родителю по горизонтали.
-
y - Контейнер является целью вертикальной привязки прокрутки для родительского контейнера прокрутки, то есть привязывается к родителю по вертикали.
-
block - Контейнер является целью привязки прокрутки по блочной оси для родительского контейнера прокрутки, то есть привязывается к родителю в блочном направлении.
-
inline - Контейнер является целью привязки прокрутки по строчной оси для родительского контейнера прокрутки, то есть привязывается к родителю в строчном направлении.
-
both - Контейнер является целью привязки прокрутки для родительского контейнера прокрутки как по горизонтали, так и по вертикали и привязывается к родителю в обоих направлениях. Контейнер не будет соответствовать условию, если он привязывается к родителю только по горизонтальной или вертикальной оси. Он должен привязываться по обеим осям.
Чтобы проверить контейнер с запросом состояния прокрутки
nonesnapped, у него должен быть родительский контейнер прокрутки со значениемscroll-snap-type, отличным отnone. Запросsnapped: noneбудет соответствовать условию даже при отсутствии родительского контейнера прокрутки.Проверки выполняются при срабатывании событий
scrollsnapchangingна контейнере привязки прокрутки. Если проверка проходит, правила внутри блока@containerприменяются к потомкам контейнера.Чтобы проверить, является ли контейнер целью привязки, не учитывая направление, используйте значение
noneс операторомnot:@container not scroll-state(snapped: none) { /* … */ } -
-
stuck - Проверяет, прикреплён ли контейнер со значением
positionstickyк краю родительского контейнера прокрутки. Допустимые значенияstuckвключают следующие ключевые слова:-
none - Контейнер не прикреплён ни к одному из краёв своего контейнера. Обратите внимание: запросы
noneбудут соответствовать условию, даже если для контейнера не заданоposition: sticky. -
top - Контейнер прикреплён к верхнему краю своего контейнера.
-
right - Контейнер прикреплён к правому краю своего контейнера.
-
bottom - Контейнер прикреплён к нижнему краю своего контейнера.
-
left - Контейнер прикреплён к левому краю своего контейнера.
-
block-start - Контейнер прикреплён к началу блочной оси своего контейнера.
-
block-end - Контейнер прикреплён к концу блочной оси своего контейнера.
-
inline-start - Контейнер прикреплён к началу строчной оси своего контейнера.
-
inline-end - Контейнер прикреплён к концу строчной оси своего контейнера.
Чтобы проверить контейнер с запросом состояния прокрутки
nonestuck, для него должно быть заданоposition: sticky, и он должен находиться внутри контейнера прокрутки. Если проверка проходит, правила внутри блока@containerприменяются к потомкам контейнераposition: sticky.Два значения для смежных осей могут соответствовать условию одновременно:
@container scroll-state((stuck: top) and (stuck: left)) { /* … */ }Однако два значения для противоположных краёв никогда не будут соответствовать условию одновременно:
@container scroll-state((stuck: left) and (stuck: right)) { /* … */ }Чтобы проверить, прикреплён ли контейнер, не учитывая направление, используйте значение
noneс операторомnot:@container not scroll-state(stuck: none) { /* … */ } -
Дескрипторы привязанных контейнеров
Дескрипторы привязанных контейнеров указываются внутри <container-condition> в качестве аргумента функции anchored(), например:
@container anchored(fallback: top) {
/* … */
}
@container anchored(fallback: flip-block flip-inline) {
/* … */
}
@container anchored(fallback: --custom-fallback) {
/* … */
}
-
fallback -
Проверяет, активен ли в данный момент конкретный резервный вариант position-try для контейнера, позиционированного относительно якоря, согласно свойству
position-try-fallbacks. Допустимыми значениямиfallbackявляются любые компоненты значения, допустимые в значении свойстваposition-try-fallbacks.Если значение
fallback, указанное в проверке, в данный момент активно для контейнера, позиционированного относительно якоря, проверка проходит, а правила внутри блока@containerприменяются к потомкам контейнера, позиционированного относительно якоря.
Формальный синтаксис
Примеры
Задание стилей в зависимости от размера контейнера
Рассмотрим следующий пример компонента карточки с заголовком и текстом:
<div class="post">
<div class="card">
<h2>Card title</h2>
<p>Card content</p>
</div>
</div>
Контекст контейнера можно создать с помощью свойства container-type, в данном случае задав значение inline-size для класса .post. Затем можно использовать at-правило @container, чтобы применить стили к элементу с классом .card внутри контейнера шириной менее 650px.
const post = document.querySelector(".post");
const span = document.createElement("span");
span.textContent = `.post width: ${post.clientWidth}px`;
post.parentNode.insertBefore(span, post.nextSibling);
// update on resize
window.addEventListener("resize", () => {
span.textContent = `.post width: ${post.clientWidth}px`;
});
span {
display: block;
text-align: center;
}
.card {
margin: 10px;
border: 2px dotted;
font-size: 1.5em;
}
.post {
border: 2px solid;
}
/* A container context based on inline size */
.post {
container-type: inline-size;
}
/* Apply styles if the container is narrower than 650px */
@container (width < 650px) {
.card {
width: 50%;
background-color: lightgray;
font-size: 1em;
}
}
Создание именованных контекстов контейнера
Рассмотрим следующий пример HTML с компонентом карточки, содержащим заголовок и текст:
<div class="post">
<div class="card">
<h2>Card title</h2>
<p>Card content</p>
</div>
</div>
Сначала создайте контекст контейнера с помощью свойств container-type и container-name. Сокращённая форма записи этого объявления описана на странице container.
.post {
container-type: inline-size;
container-name: summary;
}
Затем укажите этот контейнер, добавив его имя в запрос контейнера:
@container summary (width >= 400px) {
.card {
font-size: 1.5em;
}
}
Вложенные запросы контейнера
Нельзя указать несколько контейнеров в одном запросе контейнера. Однако можно вложить запросы контейнера, что даст тот же результат.
Следующий запрос возвращает true и применяет объявленный стиль, если ширина контейнера с именем summary превышает 400px, а ширина его родительского контейнера также превышает 800px:
@container summary (width > 400px) {
@container (width > 800px) {
/* <stylesheet> */
}
}
Запросы стилей контейнера
Запросы контейнера также могут проверять вычисленный стиль элемента-контейнера. Запрос стилей контейнера — это запрос @container, использующий одну или несколько функциональных нотаций style(). Логический синтаксис и правила объединения характеристик стиля в запрос стилей такие же, как и для запросов характеристик CSS.
@container style(<style-feature>),
not style(<style-feature>),
style(<style-feature>) and style(<style-feature>),
style(<style-feature>) or style(<style-feature>) {
/* <stylesheet> */
}
Параметр каждого style() — это одно <style-feature>. <style-feature> может быть допустимым объявлением CSS (обычная форма), свойством CSS или значением <custom-property-name> без дополнительных компонентов (логическая форма) либо сравнением диапазона (диапазонная форма).
@container style(--themeBackground),
not style(background-color: red),
style(color: green) and style(background-color: transparent),
style(--themeColor: blue) or style(--themeColor: purple) {
/* <stylesheet> */
}
Характеристика стиля без значения возвращает true, если вычисленное значение отличается от исходного значения заданного свойства.
Если <style-feature>, переданный как аргумент функции style(), является объявлением, запрос стилей возвращает true, если значение объявления совпадает с вычисленным значением этого свойства для проверяемого контейнера. В противном случае он возвращает false.
Следующий запрос контейнера проверяет, равно ли вычисленное значение свойства --accent-color элемента-контейнера значению blue:
@container style(--accent-color: blue) {
/* <stylesheet> */
}
Примечание: Если пользовательское свойство имеет значение blue, эквивалентный шестнадцатеричный код #0000ff не будет соответствовать условию, если свойство не объявлено цветом с помощью @property, чтобы браузер мог корректно сравнить вычисленные значения.
Характеристики стиля, проверяющие сокращённое свойство, возвращают true, если вычисленные значения совпадают для каждого соответствующего полного свойства, и false в противном случае. Например, @container style(border: 2px solid red) вернёт true, если все 12 полных свойств (border-bottom-style и другие), составляющих это сокращённое свойство, верны.
Обратите внимание, что в запросах стилей допускается !important, но он игнорируется.
/* !important is valid but has no effect */
@container style(--themeColor: purple !important) {
/* <stylesheet> */
}
Глобальные ключевые слова revert и revert-layer недопустимы в качестве значений в <style-feature> и приводят к тому, что запрос стилей контейнера возвращает false.
Синтаксис диапазона
Помимо описанной выше обычной формы <style-feature-name>: <value>, <style-feature> можно записать как сравнение диапазона, используя =, <, <=, > или >=. Синтаксис диапазона позволяет выполнять числовые сравнения, невозможные в обычной форме, например style(--columns >= 3) или style(--gap = 1rem). При этом разрешённые значения обеих сторон сравниваются численно.
Для вычисления диапазона браузер:
- Разрешает каждую сторону (имена пользовательских свойств ищутся так, как если бы они использовались с
var()). - Разбирает каждую сторону как
<number>,<percentage>,<length>,<angle>,<time>,<frequency>или<resolution>. Если хотя бы одну из сторон нельзя разобрать как один из этих типов или типы сторон не совпадают, запрос возвращает false. - Вычисляет каждую сторону (вычисляя все выражения
calc()) и выполняет числовое сравнение.
Это означает, что синтаксис диапазона нельзя использовать для сравнения значений, похожих на ключевые слова: style(--theme = dark) всегда возвращает false, поскольку dark не является числовым типом. Для таких значений используйте обычный синтаксис, например style(--theme: dark).
Любая сторона диапазона может быть именем пользовательского свойства, ссылкой var(), литеральным значением или выражением calc(); стороны можно указывать в любом порядке:
@container style(3 = --n) {
/* … */
}
@container style(var(--n) = 3) {
/* … */
}
@container style(calc(6/2) = var(--n)) {
/* … */
}
Диапазон также может иметь форму с тремя значениями и двумя направленными одинаково операторами сравнения, чтобы проверить, находится ли значение внутри интервала:
@container style(0 < --n < 10) {
/* true when --n is greater than 0 and less than 10 */
}
@container style(100px > --width > 50px) {
/* true when --width is less than 100px and greater than 50px */
}
Иными словами, style(0 < --n < 10) эквивалентно style(0 < --n) and style(--n < 10). Среднее значение проверяется относительно обеих границ, а не сравнивается цепочкой слева направо.
Примечание: Обычный синтаксис и синтаксис диапазона ведут себя по-разному, даже если выглядят похоже. Для --n: calc(6/2) запрос style(--n: 3) возвращает false, поскольку в обычной форме вычисленное значение свойства (calc(6/2)) напрямую сравнивается с 3. Эквивалентный запрос диапазона style(--n = 3) возвращает true, поскольку в диапазонной форме перед сравнением обе стороны вычисляются численно. Дополнительные сведения см. в разделе «Обычный синтаксис и синтаксис диапазона в запросах стилей» руководства по запросам стилей контейнера.
Запросы состояния прокрутки
Примеры запросов состояния прокрутки см. в разделе «Использование запросов состояния прокрутки контейнера».
Запросы привязанных контейнеров
Примеры запросов привязанных контейнеров см. в разделе «Использование запросов привязанных контейнеров».
Спецификации
| Спецификация |
|---|
| Модуль условных правил CSS, уровень 5 # container-type |
| Модуль позиционирования якорей CSS, уровень 2 # container-rule-anchored |
Совместимость с браузерами
| Настольные ПК | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome для Android | Firefox для Android | Opera для Android | Safari в iOS | Samsung Internet | WebView для Android | WebView в iOS | |
container |
105 |
105 |
110 |
91 |
16 |
105 |
110 |
72 |
16 |
20.0 |
105 |
16 |
anchor_position_queries |
143 |
143 |
Нет |
127 |
Нет |
143 |
Нет |
94 |
Нет |
30.0 |
143 |
Нет |
container-query_optional |
148 |
148 |
149 |
132 |
26.4 |
148 |
149 |
99 |
26.4 |
Нет |
148 |
26.4 |
scroll-state_queries |
133 |
133 |
Нет |
118 |
Нет |
133 |
Нет |
88 |
Нет |
29.0 |
133 |
Нет |
style_queries_for_custom_properties |
111 |
111 |
151 |
97 |
18Элемент document не может быть контейнером. См. ошибку 271040. |
111 |
151 |
75 |
18Элемент document не может быть контейнером. См. ошибку 271040. |
22.0 |
111 |
18Элемент document не может быть контейнером. См. ошибку 271040. |
См. также
- Использование контейнерных запросов
- Использование запросов размера и стиля контейнера
- Использование запросов состояния прокрутки контейнера
- Использование привязанных контейнерных запросов
container-namecontainer-typecontaincontent-visibility-
CSSContainerRuleAPI - Модуль изоляции CSS
- Функции ат-правил CSS
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@container