Style Donuts: CSS @scope
About me
π My name is Tyson Clugg.
I wrote my first web page using HTML 1.0 in high school back in 1994 - the year the Worldwide Web Consortium (W3C) formed. I used the <font>
tag, because CSS hadnβt even been proposed and wasnβt invented until 2 years later in 1996.
Iβve used many languages in the 20+ years Iβve been working, but my favourites are Python and Typescript. My belief is that CSS is a critically important language that all developers should learn!
Iβve been involved in many tech meetups, including Melbourne Wireless since 2000, and PostgreSQL Down Under since 2017 - both of which I helped to form and incorporate.
Iβm currently available for hire, email tyson@clugg.net or visit clugg.net/tyson if you want me on your team. π
Tip
This blog post was shown as a talk at Melbourne CSS on 2 October 2024. Join the MelCSS chat on Discord to find details of other upcoming CSS talks in Melbourne.
β
What is this?
The MDN web docs for the @scope rule introduces the @scope
feature as follows:
Letβs break that downβ¦
Limited availability
The @scope
at-rule is an experimental CSS feature, Firefox support was
added behind a feature flag from version 128 released 2024-07-09.
CSS at-rule
This is applied just like @media
rules, wrapped around one or more CSS rulesets.
Targeting elements preciselyβ¦
β¦ without writing overly specific selectors. You write simple selectors that are more specific to the content you wish to style, avoiding complex selectors such as :has()
and :not()
.
What does @scope
actually do?
It lets you apply regular CSS rulesets within a defined scope.
Given the following DOM tree example from MDN:
body
ββ article.feature
ββ section.article-hero
β ββ h2
β ββ img
β
ββ section.article-body
β ββ h3
β ββ p
β ββ img
β ββ p
β ββ figure
β ββ img
β ββ figcaption
β
ββ footer
ββ p
ββ img
If you wanted to select the <img>
element inside the <section>
with a class of article-body
, you could do the following:
- Write a selector like
.feature > .article-body > img
. However, that has high specificity so is hard to override, and is also tightly coupled to the DOM structure. If your markup structure changes in the future, you might need to rewrite your CSS. - Write something less specific like
.article-body img
. However, that will select all images inside the section.
This is where @scope
is useful. It allows you to define a precise scope inside which your selectors are allowed to target elements. For example, you could solve the above problem using a standalone @scope
block like the following:
@scope (.article-body) to (figure) {
img {
border: 5px solid black;
background-color: goldenrod;
}
}
Show me - visually
CSS syntax
@scope (article) to (blockquote) {
/* CSS rulesets here */
}
Applicable scoped selection
π© Looking at the shape of the highlighting above, we see a donut which is why we sometimes use the term donut selectors when talking about the @scope
rule.
Specificity with @scope
The @scope
at-rule doesnβt affect CSS specificity on itβs own, but you can prepend the :scope
pseudo-class to scoped selectors which adds 0-1-0
specifity to the selector:
@scope (article) to (blockquote) {
img {
/* normal specifity for <img> elements βΆ 0-0-1 */
}
:scope img {
/* adds 0-1-0 specifity for <img> elements βΆ 0-1-1 */
}
}
Note
If you havenβt learned about CSS specicifity, stop right now and take some time to complete the CSS building blocks tutorial at the Mozilla Developers Network (MDN). CSS Specificity is a fundamental CSS skill which is necessary knowledge for all web developers!
What can I use instead of @scope
?
The @scope
example below:
@scope (article) to (blockquote) {
img {
...
}
p {
...
}
}
Can be rewritten without using @scope
:
article img:not(blockquote *)
...
}
article p:not(blockquote *)
...
}
Multiple scopes
You can specify the root and limit selectors as lists, which results in multiple scopes being defined:
@scope (.article-hero, .article-body) to (figure) {
img {
border: 5px solid black;
background-color: goldenrod;
}
}
@scope
in the cascade
Inside of the CSS Cascade, @scope
also adds a new criterion: scoping proximity. The step comes after specificity but before order of appearance.
Tip
The CSS Cascade is an advanced but fundamental feature of CSS. Follow the Cascade layers lesson over at MDN to complete your understanding of this essential CSS feature.
Selector isolation, not style isolation
The @scope
at-rule limits CSS selectors, but it doesnβt prevent styles from being inherited from parent elements.
Thanks!
- Culture Amp for the π’ venue, π pizza and π₯€ drinks.
- SEEK for the π© donuts, π§ Vanilla Extract and π¨ Sprinkles.
- Zach Jensz for organising MelCSS.
Questions?
Reminder: Iβm available for hire! tyson@clugg.net
I hope youβre ready to use @scope
in your project.
Check out my blog for more articles. π
Acknowledgements
This page (and talk) was built with references from the following sources:
- MDN contributors. β@scope - CSS: Cascading Style Sheetsβ, MDN web docs.
- Bramus Van Damme. βLimit the reach of your selectors with the CSS @scope at-ruleβ, Chrome for Developers.
- Ε ime Vidas. βWeekly Platform News: Focus Rings, Donut Scope, More em Units, and Global Privacy Controlβ, CSS-Tricks.