class
Can::CssScoper
- Can::CssScoper
- Reference
- Object
Overview
Rewrites CSS to scope every selector to a given attribute.
.card { color: red }
.card:hover, h2 { color: blue }
@media (max-width: 600px) { h2 { font-size: 1rem } }
becomes (with attr data-c-foo):
.card[data-c-foo] { color: red }
.card[data-c-foo]:hover, h2[data-c-foo] { color: blue }
@media (max-width: 600px) { h2[data-c-foo] { font-size: 1rem } }
Pass-through (not scoped): @keyframes, @font-face, @import, @charset,
@page, and any unknown at-rule body. Recurses into @media, @supports,
@container, @layer blocks.
Tokenizer is brace/string/comment-aware but doesn't fully implement the CSS syntax module; uncommon edge cases (escapes inside selectors, attribute selectors with nested brackets) may not roundtrip identically.
TODO revisit per-element stamping once CSS @scope { ... } to (...) is
broadly supported (Chromium ships it; Firefox/Safari behind as of 2026).
@scope provides a real scope barrier with a stop selector, which would
let us stamp only the component's root element and wall off nested
components via to (.child-component-root). Same isolation semantics,
much lighter markup. Conservative target: revisit when all evergreen
browsers ship it and a reasonable LTS window has passed.
Defined in:
can/css_scope.crConstant Summary
-
SCOPED_AT_RULES =
{"media", "supports", "container", "layer"}