CSS @scope is an at-rule that defines the DOM region where selector rules can match. A starting selector establishes a scope root, and an optional ending selector can set a boundary. This makes it easier to express rules intended for a component, but scope does not automatically lower selector specificity or isolate the component from other CSS.

Diagram of a card scope root and an excluded nested region

The scope limits selector matching; inheritance can cross the limit.

1. A root and an optional limit

@scope (.card) { ... } uses elements matching .card as scope roots and matches selectors inside the block within that scope. The root itself can also be a candidate for matching. An element matching the limit and its descendants are excluded from that scope. That can keep an outer component's rules from extending into a nested card.

A scope is a boundary based on DOM relationships, not a separate shadow tree or style-isolation environment. Declarations outside the scope and the ordinary cascade criteria—origin, importance, layer, and specificity—continue to apply. Wrapping existing CSS in @scope therefore does not guarantee that global selectors or conflicts with another scope disappear.

2. Specificity and scoping proximity

The scope-start selector does not automatically add its specificity to selectors inside the block. An explicit :scope does add pseudo-class specificity. When other cascade criteria tie and scopes overlap, scoping proximity can help decide between declarations. A declaration whose scope root is closer to the target can take precedence, but this comparison matters only after earlier cascade stages such as origin, importance, layer, and specificity have been resolved.

So the statement “the nearest scope always wins” is incomplete. A difference in origin priority, importance, cascade layer, or specificity may determine the winner first. To debug a result, inspect the applied declarations in browser developer tools and review both the scope-root relationship and the full cascade order.

3. Nested components and scope limits

A scope limit can restrict how far an outer component's rules reach into nested components. For example, a .card scope with a nested .card as its limit can exclude that inner card from the outer scope. The inner component's own rules and any more specific selectors still need to be considered separately.

This can make component CSS easier to read and may reduce conflicts in class naming, but it is not the same as style encapsulation. For example, color can still be inherited by the limit element and its descendants. Restricting selector matching does not block inheritance. Test the actual nested DOM and verify that the scope limit creates the intended boundary.

4. Expert perspective: declare and verify the boundary

The cited CSSWG document is a work-in-progress Editors Draft. It defines & nested directly inside @scope like :where(:scope); this draft language should not be presented as a stable W3C Recommendation.

When adopting it, align roots and limits with clear component boundaries and check which selectors match in nested markup. This is a simplified account of cascade ordering. When earlier criteria tie, scoping proximity is compared after specificity and before order of appearance. Confirm support for the browsers in scope and provide fallback styling where needed. @scope is a useful way to express selector boundaries, not a replacement for the cascade itself.

Sources