Skip to content

[css-cascade-6] Add implicit scopes #8463

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 17, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 59 additions & 24 deletions css-cascade-6/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Informative Classes: ex

<pre class=link-defaults>
spec:dom; type:dfn; text:shadow tree
spec:dom; type:dfn; for:tree; text:root
spec:css-color-4; type:property; text:color
spec:css-values-3; type: value; text:ex
spec:css-conditional-3; type:at-rule; text:@media
Expand Down Expand Up @@ -233,27 +234,26 @@ Scoped Styles</h2>

A <dfn>scope</dfn> is a subtree or fragment of a document,
which can be used by selectors for more targeted matching.
[=Scopes=] are described in CSS through a combination of two selector lists:

* The <dfn><<scope-start>></dfn> is a <<forgiving-selector-list>>.
Each element matched by <<scope-start>> is a [=scoping element=],
creating a scope with itself as the [=scoping root=].
* The <dfn><<scope-end>></dfn> is a <<forgiving-selector-list>>
that is [=scoped selector|scoped=] by the <<scope-start>> selector,
with the [=scoping roots=] as [=:scope elements=].
Each element matched by <<scope-end>> is a [=scoping limit=].
The <dfn>scoping limit</dfn> elements define the lower bounds of a scope,
so that [=scoped selectors=] are not able to match
any [=scoping limit=] elements,
or any elements nested within them.

Each resulting [=scope=] includes a [=scoping root=] and all its descendants,
up to any [=scoping limit=] elements. [=Scoping limit=] elements and
their descendants are not included in the [=scope=].

[=Pseudo-elements=] cannot be [=scoping roots=] or [=scoping limits=];
they are invalid both within <<scope-start>> and <<scope-end>>.

A [=scope=] can be formed by determining:

* The [=scoping root=] [=node=],
which acts as the upper bound of the scope,
and optionally:
* The <dfn>scoping limit</dfn> elements,
which act as the lower bounds.

An element is <dfn>in scope</dfn> if:

* It is an [=inclusive descendant=] of the [=scoping root=], and
* It is not an [=inclusive descendant=] of a [=scoping limit=].

Note: Only <em>elements</em> can be [=in scope=],
however the '':scope'' pseudo-class can match non-elements
when it is not the [=subject=] of a selector.

[=Scopes=] are described in CSS using the ''@scope'' rule.

Note: In contrast to [[CSS-SCOPING-1#shadow-dom|Shadow Encapsulation]],
which describes a persistent one-to-one relationship in the DOM
between a [=shadow host=] and its nested [=shadow tree=],
Expand Down Expand Up @@ -351,17 +351,49 @@ Scoping Styles: the ''@scope'' rule</h4>

The syntax of the ''@scope'' rule is:

<pre class='prod'>
@scope (<<scope-start>>) [to (<<scope-end>>)]? {
<pre class="prod def">
@scope [(<<scope-start>>)]? [to (<<scope-end>>)]? {
<<stylesheet>>
}
</pre>

where:

<pre class="prod def">
<dfn><<scope-start>></dfn> = <<forgiving-selector-list>>
<dfn><<scope-end>></dfn> = <<forgiving-selector-list>>
</pre>

A ''@scope'' rule which specifies a <<scope-start>>
produces a number of <dfn>explicit scopes</dfn> as follows:

* For each element matched by <<scope-start>>,
create a [=scope=] using that element as the [=scoping root=].
* For each [=scope=] created by the above:
* Collect all elements that are [=in scope=]
and that match <<scope-end>>,
using the [=scoping root=] as the '':scope'' element, then
* Set those elements as the [=scoping limits=].

[=Pseudo-elements=] cannot be [=scoping roots=] or [=scoping limits=];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After moving this above in the previous PR, I moved it back down! 😅

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:-)

they are invalid both within <<scope-start>> and <<scope-end>>.

A ''@scope'' rule which does not specify a <<scope-start>>
produces a single <dfn>implicit scope</dfn> as follows:

* The [=scoping root=] is the [=parent element=] of the [=owner node=]
of the stylesheet where the ''@scope'' rule is defined.
If no such element exist,
then the [=scoping root=] is the [=root=] of the containing [=node tree=].
* The [=scoping limits=] are unset;
[=implicit scopes=] do not have lower bounds.

The ''@scope'' [=at-rule=] has three primary effects
on the [=style rules=] in its <<stylesheet>>:

* [=scoped selectors|Selectors are scoped=] to the given [=scope=],
with the [=:scope element=] being the [=scoping root=].
* Selectors can only match elements that are [=in scope=].
This only applies to the [=subject=];
the rest of the selector can match unrestricted.
* Selectors are given the added specificity of
the most specific [=complex selector=] in the <<scope-start>> argument.

Expand Down Expand Up @@ -562,6 +594,9 @@ Changes since the 21 December 2021 First Public Working Draft</h3>
Significant changes since the
<a href="https://www.w3.org/TR/2021/WD-css-cascade-6-20211221/">21 December 2021 First Public Working Draft</a> include:

* Added [=implicit scopes=].
(<a href="https://github.com/w3c/csswg-drafts/issues/6606">Issue 6606</a>)

* Disallowed [=pseudo-elements=] in the ''@scope'' prelude.
(<a href="https://github.com/w3c/csswg-drafts/issues/7382">Issue 7382</a>)

Expand Down