Day 102: selecting the scoping root
source link: https://www.matuzo.at/blog/2023/100daysof-day102/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Day 102: selecting the scoping root
posted on September 1., 2023
It’s time to get me up to speed with modern CSS. There’s so much new in CSS that I know too little about. To change that I’ve started #100DaysOfMoreOrLessModernCSS. Why more or less modern CSS? Because some topics will be about cutting-edge features, while other stuff has been around for quite a while already, but I just have little to no experience with it.
There are different ways of selecting the scoping root inside a @scope
rule.
When you use the :scope
pseudo-class in a stylesheet, it matches the :root
element.
:root {
border: 10px solid red;
}
:scope {
border-color: blue;
}
/* -> 10px blue border on the <html> element */
When you use it inside a scope rule, it matches the rule's scoping root.
<div class="wrapper">
<div class="content">
the cascade is unavoidable
</div>
</div>
@scope (.wrapper) {
:scope {
border: 5px solid red;
}
}
/* -> 5px red border on the .wrapper element */
Selectors inside a scope rule can only match elements that are in scope. Selecting .content
within the .wrapper
scope works:
@scope (.wrapper) {
.content {
background: aqua;
}
}
/* That's like writing .wrapper .content {} */
Selecting .wrapper .content
within the .wrapper
scope doesn't work:
@scope (.wrapper) {
.wrapper .content {
background: aqua;
}
}
/* That's like writing .wrapper .wrapper .content {} */
You can use :scope
instead of .wrapper
. That works because it doesn't match an element with the class .wrapper
inside of .wrapper
, but the scoping root itself.
@scope (.wrapper) {
:scope .content {
background: aqua;
}
}
/* That's like writing .wrapper .content {} */
Instead of .scope
, you can also use &
.
@scope (.wrapper) {
& {
border: 5px solid orange;
}
& .content {
background: aqua;
}
}
/*
-> 5px orange border on the .wrapper element
and aqua background on .content.
*/
There are two differences between :scope
and &
in this context. They're only evident if you have a list of scoping roots.
The first difference in specificity. :scope
has the specificity of a pseudo-class. &
takes on the specificity of the most specific selector in the selector list of scoping roots. In the following example :scope
overrules &
because &
has the specificity of a tag selector.
<section id="section">
<h2>
<span>yo!</span>
</h2>
<p>
<span>yo!</span>
</p>
</section>
@scope (section, p) {
:scope {
border: 10px solid green;
}
& {
border: 10px solid red;
}
}
/* -> 10px green border on section and p */
If you scope the section via its id instead of the tag, &
takes on the specificity of an id selector and thus overrules :scope
.
@scope (#section, p) {
& {
border: 10px solid red;
}
:scope {
border: 10px solid green;
}
}
/* -> 10px red border on the section and p */
The second difference is that :scope
only matches the scoping root itself. &
can match any element that is matched by the selector list.
<section>
<h2>
<span>yo!</span>
</h2>
<p>
<span>yo!</span>
</p>
</section>
@scope (section, p) {
:scope span { background: fuchsia; }
/*
section span { }
p span { }
-> fuchsia background on span within h2 and p
*/
:scope & span { background: aqua; }
/*
section p span { }
-> aqua background only on span within p
*/
:scope :scope span { background: red }
/*
Doesn't match any element because `@scope (section, p)` only
defines multiple scopes, it doesn't nest them.
*/
}
Essentially, that means that :scope
can only match a scoping root and &
can match an element in the selector list, regardless of whether it's considered a scoping root in that context. At least, that's how I interpret it. The spec is still pretty fucking hard to read.
To try out @scope
you have to download Chrome Canary and enable the Experimental Web Platform features
flag in chrome://flags/.
Further reading
Want more?
Overview: 100 Days Of More Or Less Modern CSS
My blog doesn't support comments yet, but you can reply via e-mail.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK