Name-Only Containers: The Scoping We Needed
Name-Only Containers: The Scoping We Needed ź“ė Ø
Iāve done my time thinking about scope in CSS. Iāve done it my whole career, and did a presentation on it recently that I wrote up in full here. That was on the heels of @scope becoming a thing in CSS, which is, naturally, a part of the scope in CSS story.
I donāt entirely dislike It can do three things, all of which I find quite niche:@scope, but I guess Iām comfortable saying Iām disappointed in it.
- Donut scoping
- Proximity specificity
- DOM blasters
I covered these in my talk. They have their uses, but again: niche.
Update
Actually @scope⦠also does what I talk about in this post. And arguably, it does it better because the purpose is more aligned with the name, and it has deeper browser support. Iāll add an additional section below showing how similar it is.
:::
The kind of scoping that I want in CSS is the kind that weāve been given by tools like <style scoped> in .vue files and Svelte components, and more broadly, what CSS modules does (css-modules/css-modules).
I want to write:
.card {
}
And have it turned into something like:
[data-style="apio087df"] {
/* Or, .card-apio087df */
/* But I kinda like the data-attribute approach
better because it leaves the original class alone */
}
(And have that attribute applied to my HTML so the new selector works.)
The reason I want that is that I donāt want to worry about a class name Iām writing conflicting with an existing class. I just donāt want to think about it. Ever, ideally.
I donāt need this on every project I touch; I want it on large-scale projects with many components and numerous style changes maintained over many years.
To me, thatās a scoped style.
I already get it with CSS modules, and thatās fine. But Iām a big fan when the web platform steps in and helps us do things weād otherwise need a build process and tooling for. ~Thatās what we didnāt get with @scope.~
Another option is just to make all your class names unique. This works on the vast majority of projects and requires no technology we didnāt have pretty much since HTML and CSS began life.
If class name scoping is all you or I ever do, thatās OK. I can live with that.

But wait, name-only containers?
I read in the Safari 26.4 release notes that Safari is now supporting name-only containers. Like this:
/* Name a container */
.sidebar {
container-name: sidebar;
container-type: inline-size;
}
/* Write styles with that name only, no conditions */
@container sidebar {
.card {
padding: 1rem;
}
}
No conditions? Isnāt the whole point of a container to style based on conditions (like, 98% of the time, being how wide it is)?
Well, not if the only effect we want from this is scoping! (!!!)
Components typically already have unique names.
Because components typically live in folders and folders have to have different names, components already have a forced uniqueness constraint.

Letās just consider three. Hereās three design system (ds) components:
<ds-card><ds-article><ds-header>
Styles in Components
Each of them has styles that get bundled into global CSS:
- ds-card.css
- ds-article.css
- ds-header.css
Note
Weāre not talking shadow DOM and web components here, Iām talking very generally about any design system of components, regardless of framework.
Both a card and an article can very easily have a title. Itās entirely reasonable to write a class like:
.title {
background: rebeccapurple;
color: white;
}
.title {
font-weight: 300;
letter-spacing: -0.01em;
}
Just some contrived styles there. Those will overlap and both apply because of the identical class names in use.
Usually thatās not what we want. Usually we avoid this by just career-long muscle memory of knowing this and perhaps some BEM methodology or nesting.
ds-card {
.title {
/* Title styles unique to the card */
}
}
Thatās artificial specificity boosting just to avoid future trouble. Not the end of the world, but not ideal.
It feels nicer not to think about it, which is what we get in a CSS modules approach. The styles canāt clash because they are programmatically randomized. And we donāt have to nest either, meaning weāre not bumping up specificity just for scoping.
Scoping Styles in Components
Letās say we use the name of the component as the CSS container-name for every component.
ds-card {
container-name: ds-card;
}
ds-article {
container-name: ds-article;
}
ds-header {
container-name: ds-header;
}
Now in the stylesheet for each of those components (which is again, probably bundled and put into global scope like regular CSS).
@container ds-card {
}
@container ds-article {
}
@container ds-header {
}
Now I can do literally anything I want inside those @container blocks and it will not globally conflict.
@container ds-card {
.title {
background: rebeccapurple;
color: white;
}
}
@container ds-article {
.title {
font-weight: 300;
letter-spacing: -0.01em;
}
}
@container ds-header {
}
No conflicts there. Same class name, but scoped inside the relevant containers.
Thatās it! Thatās the scoping power we want.
And Iām fairly certain⦠no side effects. The WebKit blog post uses a container-type: inline-size, which would have side effects, but in my testing, that doesnāt seem necessary.
, we can do this with @scope too.
Rather than this @container stuff we just looked atā¦
ds-card {
container-name: ds-card;
}
@container ds-card {
button {
/* I'm safe! */
}
}
We can do the same exact thing with @scope. (Credit: Miriam(miriam.codes))
@scope (ds-card) {
button {
/* I'm safe */
}
}
Thereās really no difference here, except that weāre not explicitly naming the scope (which, for some reason, my brain likes), weāre leaning on a scoped selector. The selector could be whatever, like a specifically named attribute or something.
Demo
Name-only container styles I belive are only support in Safari 26.4+, so hereās hoping for broader support soon.
This is related to several other ideological approaches Iām already a fan of:
Pretty satisfying to see this evolve.
Letās see Chrome & Firefox pick up these name-only containers, and letās see Safari pick up import type assertions plz thx.