Styles that stop at a boundary you name
inside the scope
past the limit, untouched
Caveat@scope is not encapsulation. It limits where these rules apply and does nothing to stop rules from anywhere else reaching in — a stray p { color: red } in another sheet still wins on specificity and still paints the inner block. Reaching for it expecting shadow-DOM behaviour gets you the opposite of what you expected, quietly. The limit is also exclusive: to (.inner) leaves .inner itself outside the scope, so you cannot style the boundary element from within.
FallbackAn engine without it drops the entire block, so scoped rules simply never apply. Safe as an enhancement, unsafe as the only place a needed style lives: put the styles that must exist outside the block and use the scope for the ones that refine them.
/* from .outer, down to but not
including .inner */
@scope (.outer) to (.inner) {
p { color: CanvasText; }
}
/* still reaches in — @scope is not
a wall, only a range */
p { color: red; }
Published
Questions
Why does a global style still override my @scope rules?
Specificity is compared before scope proximity, so any more specific selector from another sheet beats the scoped rule. The scope root adds nothing to the specificity of the selectors inside the block, so p in @scope (.outer) still weighs one type selector.
Why is the element in the to() limit not styled by @scope?
The lower boundary is exclusive: to (.inner) stops the scope just above .inner. To pull the limit element in and exclude only its contents, write to (.inner > *). The root itself is inside the scope and is reachable with :scope.
Can I use @scope inside a style tag without a selector?
Yes. A bare @scope { } inside a <style> element takes that element's parent as its scope root, so the rules apply to the parent and its descendants only.