Spec-Zone.ru › CSS

Правило 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
Контейнер является целью привязки прокрутки для родительского контейнера прокрутки как по горизонтали, так и по вертикали и привязывается к родителю в обоих направлениях. Контейнер не будет соответствовать условию, если он привязывается к родителю только по горизонтальной или вертикальной оси. Он должен привязываться по обеим осям.

Чтобы проверить контейнер с запросом состояния прокрутки none snapped, у него должен быть родительский контейнер прокрутки со значением scroll-snap-type, отличным от none. Запрос snapped: none будет соответствовать условию даже при отсутствии родительского контейнера прокрутки.

Проверки выполняются при срабатывании событий scrollsnapchanging на контейнере привязки прокрутки. Если проверка проходит, правила внутри блока @container применяются к потомкам контейнера.

Чтобы проверить, является ли контейнер целью привязки, не учитывая направление, используйте значение none с оператором not:

@container not scroll-state(snapped: none) {
  /* … */
}
stuck
Проверяет, прикреплён ли контейнер со значением position sticky к краю родительского контейнера прокрутки. Допустимые значения stuck включают следующие ключевые слова:
none
Контейнер не прикреплён ни к одному из краёв своего контейнера. Обратите внимание: запросы none будут соответствовать условию, даже если для контейнера не задано position: sticky.
top
Контейнер прикреплён к верхнему краю своего контейнера.
right
Контейнер прикреплён к правому краю своего контейнера.
bottom
Контейнер прикреплён к нижнему краю своего контейнера.
left
Контейнер прикреплён к левому краю своего контейнера.
block-start
Контейнер прикреплён к началу блочной оси своего контейнера.
block-end
Контейнер прикреплён к концу блочной оси своего контейнера.
inline-start
Контейнер прикреплён к началу строчной оси своего контейнера.
inline-end
Контейнер прикреплён к концу строчной оси своего контейнера.

Чтобы проверить контейнер с запросом состояния прокрутки none stuck, для него должно быть задано 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). При этом разрешённые значения обеих сторон сравниваются численно.

Для вычисления диапазона браузер:

  1. Разрешает каждую сторону (имена пользовательских свойств ищутся так, как если бы они использовались с var()).
  2. Разбирает каждую сторону как <number>, <percentage>, <length>, <angle>, <time>, <frequency> или <resolution>. Если хотя бы одну из сторон нельзя разобрать как один из этих типов или типы сторон не совпадают, запрос возвращает false.
  3. Вычисляет каждую сторону (вычисляя все выражения 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-name
  • container-type
  • contain
  • content-visibility
  • CSSContainerRule API
  • Модуль изоляции 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API