Skip to content
Merged
52 changes: 14 additions & 38 deletions files/en-us/web/css/@scope/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,21 +129,19 @@ In the context of a `@scope` block, the {{cssxref(":scope")}} pseudo-class repre
}
```

In fact, `:scope` is implicitly prepended to all scoped style rules. If you want, you can explicitly prepend `:scope` or prepend the [nesting](/en-US/docs/Web/CSS/CSS_nesting) selector (`&`) to get the same effect if you find these representations easier to understand.

The three rules in the following block are all equivalent in what they select:
In the following code snippet, the three rules select the same element, but differ in specificity (see [Specificity in @scope](#specificity_in_scope) for details):

```css
@scope (.feature) {
img {
/* … */
}

:scope img {
& img {
/* … */
}

& img {
:scope img {
/* … */
}
}
Expand Down Expand Up @@ -184,53 +182,31 @@ The three rules in the following block are all equivalent in what they select:

### Specificity in `@scope`

Including a ruleset inside a `@scope` block does not affect the specificity of its selector, regardless of the selectors used inside the scope root and limit. For example:
Inside an `@scope` rule, both bare selectors and `&` are treated as if `:where(:scope)` were prepended, meaning they select the scope root with zero specificity.
Because [`:where()`](/en-US/docs/Web/CSS/:where) has zero specificity, the only specificity comes from `img` (`0-0-1`).

```css
@scope (.article-body) {
/* img has a specificity of 0-0-1, as expected */
img {
/* … */
}
}
```

However, if you decide to explicitly prepend the `:scope` pseudo-class to your scoped selectors, you'll need to factor it in when calculating their specificity. `:scope`, like all regular pseudo-classes, has a specificity of 0-1-0. For example:

```css
@scope (.article-body) {
/* :scope img has a specificity of 0-1-0 + 0-0-1 = 0-1-1 */
:scope img {
/* … */
}
}
```

When using the `&` selector inside a `@scope` block, `&` represents the scope root selector; it is internally calculated as that selector wrapped inside an {{cssxref(":is", ":is()")}} pseudo-class function. So for example, in:

```css
@scope (figure, #primary) {
/* & img also has a specificity of 0-0-1 */
& img {
/* … */
}
}
```

`& img` is equivalent to `:is(figure, #primary) img`. Since `:is()` takes the specificity of its most specific argument (`#primary`, in this case), the specificity of the scoped `& img` selector is therefore 1-0-0 + 0-0-1 = 1-0-1.

### The difference between `:scope` and `&` inside `@scope`

`:scope` represents the matched scope root, whereas `&` represents the selector used to match the scope root. Because of this, it is possible to chain `&` multiple times. However, you can only use `:scope` once — you can't match a scope root inside a scope root.
By contrast, using `:scope` explicitly selects the scope root with class specificity.
Like other pseudo-classes, `:scope` has a specificity of `0-1-0`.
In the following example, `:scope img` has a specificity of `0-1-1`:

```css
@scope (.feature) {
/* Selects a .feature inside the matched root .feature */
& & {
/* … */
}

/* Doesn't work */
:scope :scope {
@scope (.article-body) {
/* :scope img has a specificity of 0-1-0 + 0-0-1 = 0-1-1 */
:scope img {
/* … */
}
}
Expand Down Expand Up @@ -370,7 +346,7 @@ div {

The above code renders like this:

{{ EmbedLiveSample("Basic style inside scope roots", "100%", "150") }}
{{EmbedLiveSample("Basic style inside scope roots", "100%", "150")}}

### Scope roots and scope limits

Expand Down Expand Up @@ -481,7 +457,7 @@ In our CSS, we have two `@scope` blocks:

In the rendered code, note how all of the `<img>` elements are styled with the thick border and golden background, except for the one inside the `<figure>` element (labeled "My infographic").

{{ EmbedLiveSample("Scope roots and scope limits", "100%", "400") }}
{{EmbedLiveSample("Scope roots and scope limits", "100%", "400")}}

## Specifications

Expand Down