CSS-правило-ат-правило `@scope`
Базовая поддержка Недавно стало доступно
Эта функция работает в последних версиях устройств и браузеров. Она может не работать на старых устройствах и в старых версиях браузеров. Поддержка во всех браузерах доступна с марта 2026 года.
@scope CSS правило-ат-правило позволяет выбирать элементы в определённых поддеревьях DOM, точно задавая целевые элементы без написания чрезмерно специфичных селекторов, которые сложно переопределять, и без слишком тесной привязки селекторов к структуре DOM.
В JavaScript доступ к @scope можно получить через интерфейс объектной модели CSS CSSScopeRule.
Синтаксис
Правило-ат-правило @scope содержит один или несколько наборов правил (называемых ограниченными по области действия правилами стилей) и определяет область, в которой они применяются к выбранным элементам. @scope можно использовать двумя способами:
-
Как отдельный блок внутри CSS. В этом случае он содержит вступительную часть с селекторами корня области и необязательного ограничителя области — они задают верхнюю и нижнюю границы области.
@scope (scope root) to (scope limit) { /* … */ } -
Как встроенные стили внутри элемента
<style>в HTML. В этом случае вступительная часть опускается, а заключённый в нём набор правил автоматически ограничивается родительским элементом, содержащим элемент<style>.<parent-element> <style> @scope { /* rulesets */ } </style> </parent-element>Также можно объединить встроенное
@scopeс селектором ограничителя области, как в@scope to (scope limit) { ... }.
Описание
Сложный веб-документ может включать такие компоненты, как заголовки, нижние колонтитулы, новостные статьи, карты, медиаплееры, рекламные объявления и другие. По мере роста сложности становится всё важнее эффективно управлять стилями этих компонентов, а грамотное ограничение области действия стилей помогает справиться с этой сложностью. Рассмотрим следующее дерево DOM:
body
└─ article.feature
├─ section.article-hero
│ ├─ h2
│ └─ img
│
├─ section.article-body
│ ├─ h3
│ ├─ p
│ ├─ img
│ ├─ p
│ └─ figure
│ ├─ img
│ └─ figcaption
│
└─ footer
├─ p
└─ img
Чтобы выбрать элемент <img> внутри <section> с классом article-body, можно сделать следующее:
- Написать селектор вида
.feature > .article-body > img. Однако у него высокая специфичность, поэтому его сложно переопределить; кроме того, он жёстко привязан к структуре DOM. Если в будущем структура разметки изменится, возможно, придётся переписать CSS. - Написать менее специфичный селектор, например
.article-body img. Однако он выберет все изображения внутриsection.
В этом случае пригодится @scope. Оно позволяет определить точную область, внутри которой селекторы могут выбирать элементы. Например, решить описанную выше задачу можно с помощью отдельного блока @scope:
@scope (.article-body) to (figure) {
img {
border: 5px solid black;
background-color: goldenrod;
}
}
Селектор корня области .article-body определяет верхнюю границу области дерева DOM, в которой будет применяться набор правил, а селектор ограничителя области figure определяет нижнюю границу. В результате будут выбраны только элементы <img> внутри <section> с классом article-body, но не внутри элементов <figure>.
Примечание: Такое ограничение области — с верхней и нижней границами — обычно называют областью-пончиком.
Верхняя граница области включается в неё, а нижняя — нет. Чтобы изменить это поведение, можно объединить любой из селекторов с универсальным селектором дочернего элемента. Например, @scope (scope root) to (scope limit > *) сделает обе границы включительными, @scope (scope root > *) to (scope limit) сделает обе границы исключительными, а @scope (scope root > *) to (scope limit > *) задаст исключительную верхнюю и включительную нижнюю границу.
Чтобы выбрать все изображения внутри <section> с классом article-body, можно опустить ограничитель области:
@scope (.article-body) {
img {
border: 5px solid black;
background-color: goldenrod;
}
}
Можно также поместить блок @scope внутрь элемента <style>, который, в свою очередь, находится внутри <section> с классом article-body:
<section class="article-body">
<style>
@scope {
img {
border: 5px solid black;
background-color: goldenrod;
}
}
</style>
<!-- ... -->
</section>
Примечание: Важно понимать, что, хотя @scope позволяет ограничить применение селекторов определёнными поддеревьями DOM, оно не изолирует стили полностью внутри этих поддеревьев. Особенно заметно это при наследовании: свойства, наследуемые дочерними элементами (например, color или font-family), будут по-прежнему наследоваться за пределами заданного ограничителя области.
Псевдокласс :scope внутри блоков @scope
В контексте блока @scope псевдокласс :scope позволяет удобно применять стили непосредственно к корню области:
@scope (.feature) {
:scope {
background: rebeccapurple;
color: antiquewhite;
font-family: sans-serif;
}
}
При использовании :scope внутри блоков @scope следует учитывать следующее:
-
:scopeдобавляет специфичность уровня класса (подробности см. в разделе Специфичность в @scope). -
В ограничителе области можно использовать
:scope, чтобы задать требование к взаимному расположению ограничителя области и корня. Например:/* figure is only a limit when it is a direct child of the :scope */ @scope (.article-body) to (:scope > figure) { /* … */ } -
Ограничитель области может ссылаться на элементы за пределами корня области с помощью
:scope. Например:/* figure is only a limit when the :scope is inside .feature */ @scope (.article-body) to (.feature :scope figure) { /* … */ } -
Ограниченные по области действия правила стилей не могут выходить за пределы поддерева. Такие выборки, как
:scope + p, недопустимы, поскольку выбранный элемент находился бы за пределами поддерева. -
Корень и ограничитель области можно задать как список селекторов; в этом случае будут определены несколько областей. В следующем примере стили применяются к любому
<img>внутри<section>с классомarticle-heroилиarticle-body, но не если оно вложено в<figure>:@scope (.article-hero, .article-body) to (figure) { img { border: 5px solid black; background-color: goldenrod; } }
Специфичность в @scope
Внутри правила @scope как простые селекторы, так и селектор вложенности & ведут себя так, как если бы перед ними был добавлен :where(:scope). Поскольку :where() имеет нулевую специфичность, простые селекторы и & не добавляют вес. Вес специфичности определяется остальной частью селектора. Например, специфичность селектора & img эквивалентна специфичности :where(:scope) img (0-0-1).
Предупреждение: Специфичность & внутри блоков @scope обрабатывается по-разному в зависимости от движка браузера и версии выпуска. Подробнее см. в разделе Совместимость с браузерами.
В обоих случаях в следующем блоке кода единственный вклад в специфичность вносит img:
@scope (.article-body) {
/* img has a specificity of 0-0-1, as expected */
img {
/* … */
}
/* & img also has a specificity of 0-0-1 */
& img {
/* … */
}
}
Напротив, явное использование :scope выбирает корень области и добавляет специфичность уровня класса (0-1-0), поскольку :scope — это псевдокласс. В следующем блоке кода специфичность :scope img равна 0-1-1:
@scope (.article-body) {
/* :scope img has a specificity of 0-1-0 + 0-0-1 = 0-1-1 */
:scope img {
/* … */
}
}
Разрешение конфликтов @scope
@scope добавляет новый критерий в каскад CSS: близость области действия. Согласно этому критерию, если стили двух областей конфликтуют, применяется стиль области, до корня которой от элемента по иерархии дерева DOM меньше переходов. Рассмотрим пример, чтобы понять, что это означает.
Возьмём следующий фрагмент HTML, где карточки с разными темами вложены друг в друга:
<div class="light-theme">
<p>Light theme text</p>
<div class="dark-theme">
<p>Dark theme text</p>
<div class="light-theme">
<p>Light theme text</p>
</div>
</div>
</div>
Если написать CSS для тем следующим образом, возникнет проблема:
.light-theme {
background: #cccccc;
}
.dark-theme {
background: #333333;
}
.light-theme p {
color: black;
}
.dark-theme p {
color: white;
}
Предполагалось, что внутренний абзац будет чёрным, поскольку он находится внутри карточки со светлой темой. Однако на него нацелены и .light-theme p, и .dark-theme p. Поскольку правило .dark-theme p расположено позже в исходном коде, применяется именно оно, и абзац ошибочно становится белым.
Исправить это можно с помощью @scope:
@scope (.light-theme) {
:scope {
background: #cccccc;
}
p {
color: black;
}
}
@scope (.dark-theme) {
:scope {
background: #333333;
}
p {
color: white;
}
}
Теперь внутренний абзац правильно отображается чёрным. Это происходит потому, что от него до корня области .light-theme всего один уровень дерева DOM, а до корня области .dark-theme — два. Поэтому приоритет получает стиль светлой темы.
Примечание: Близость области действия важнее порядка в исходном коде, но сама уступает другим критериям с более высоким приоритетом, таким как важность, слои и специфичность.
Формальный синтаксис
Примеры
Базовые стили внутри корней областей
В этом примере мы используем два отдельных блока @scope, чтобы выбрать ссылки внутри элементов с классами .light-scheme и .dark-scheme соответственно. Обратите внимание, как :scope используется для выбора корней областей и применения к ним стилей. В этом примере корнями областей являются элементы <div>, которым назначены эти классы.
HTML
<div class="light-scheme">
<p>
MDN contains lots of information about
<a href="/en-US/docs/Web/HTML">HTML</a>,
<a href="/en-US/docs/Web/CSS">CSS</a>, and
<a href="/en-US/docs/Web/JavaScript">JavaScript</a>.
</p>
</div>
<div class="dark-scheme">
<p>
MDN contains lots of information about
<a href="/en-US/docs/Web/HTML">HTML</a>,
<a href="/en-US/docs/Web/CSS">CSS</a>, and
<a href="/en-US/docs/Web/JavaScript">JavaScript</a>.
</p>
</div>
CSS
div {
padding: 10px;
}
@scope (.light-scheme) {
:scope {
background-color: plum;
}
a {
color: darkmagenta;
}
}
@scope (.dark-scheme) {
:scope {
background-color: darkmagenta;
color: antiquewhite;
}
a {
color: plum;
}
}
Результат
Приведённый выше код отображается следующим образом:
Корни и ограничители областей
В этом примере фрагмент HTML соответствует структуре DOM, которую мы ранее рассмотрели в разделе Описание. Эта структура представляет собой типичное краткое содержание статьи. Обратите внимание на элементы <img>, вложенные на разных уровнях структуры.
Цель этого примера — показать, как с помощью корня и ограничителя области стилизовать элементы <img>, начиная с верхнего уровня иерархии, но только до элемента <img> внутри элемента <figure> (не включая его), фактически создав область-пончик.
HTML
<article class="feature">
<section class="article-hero">
<h2>Article heading</h2>
<img alt="image" src="" />
</section>
<section class="article-body">
<h3>Article subheading</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam euismod
consectetur leo, nec eleifend quam volutpat vitae. Duis quis felis at
augue imperdiet aliquam. Morbi at felis et massa mattis lacinia. Cras
pharetra velit nisi, ac efficitur magna luctus nec.
</p>
<img alt="image" src="" />
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<figure>
<img alt="image" src="" />
<figcaption>My infographic</figcaption>
</figure>
</section>
<footer>
<p>Written by Chris Mills.</p>
<img alt="image" src="" />
</footer>
</article>
CSS
* {
box-sizing: border-box;
}
article {
margin-bottom: 20px;
padding: 10px;
border: 2px solid gray;
}
.article-hero,
.article-body,
article footer {
padding: 20px;
margin: 10px;
border: 2px solid lightgray;
}
img {
height: 100px;
width: 100%;
display: block;
background-color: lightgray;
color: black;
padding: 10px;
}
В CSS у нас есть два блока @scope:
- Первый блок
@scopeзадаёт корнем области элементы с классом.feature(в данном случае только внешний<article>), демонстрируя, как@scopeможно использовать для оформления определённой части HTML. - Второй блок
@scopeтакже задаёт корнем области элементы с классом.feature, но дополнительно определяет ограничитель областиfigure. Благодаря этому содержащиеся в нём наборы правил применяются только к подходящим элементам внутри корня области (в данном случае<article class="feature"> ... </article>), которые не вложены в дочерние элементы<figure>. Этот блок@scopeсодержит один набор правил, который задаёт для элементов<img>толстую чёрную рамку и золотистый цвет фона.
/* Scoped CSS */
@scope (.feature) {
:scope {
background: rebeccapurple;
color: antiquewhite;
font-family: sans-serif;
}
figure {
background-color: white;
border: 2px solid black;
color: black;
padding: 10px;
}
}
/* Donut scope */
@scope (.feature) to (figure) {
img {
border: 5px solid black;
background-color: goldenrod;
}
}
Результат
В отображённом результате обратите внимание, что все элементы <img> оформлены толстой рамкой и золотистым фоном, кроме элемента внутри <figure> (с подписью «Моя инфографика»).
Спецификации
| Спецификация |
|---|
| Каскадирование и наследование CSS, уровень 6 # scoped-styles |
| Модуль вложенности CSS, уровень 1 # nesting-at-scope |
Совместимость с браузерами
| Настольные компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome для Android | Firefox для Android | Opera для Android | Safari для iOS | Samsung Internet | WebView для Android | WebView для iOS | |
scope |
118 |
118 |
146 |
104 |
26.4
26–26.4Правила CSS внутри@scope не применяются к элементам <input> и <textarea>.17.4–26
|
118 |
146 |
79 |
26.4
26–26.4Правила CSS внутри@scope не применяются к элементам <input> и <textarea>.17.4–26
|
25.0 |
118 |
26.4
26–26.4Правила CSS внутри@scope не применяются к элементам <input> и <textarea>.17.4–26
|
at-scope |
143 |
143 |
142 |
127 |
26.2 |
143 |
142 |
94 |
26.2 |
30.0 |
143 |
26.2 |
См. также
:scopeCSSScopeRule- Специфичность
-
Определение селектора
&в правиле@scopeна css.oddbird.net (2025) -
Ограничение области действия селекторов с помощью правила-ат-правила CSS
@scopeна developer.chrome.com (2023)
© 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/@scope