Skip to main content

scope_css

Function scope_css 

Source
pub fn scope_css(css: &str, scope_id: &str) -> String
Expand description

Rewrite a CSS stylesheet so every selector compound carries the scope attribute, preserving combinators between compounds:

.header h1 { ... }   ->  .header[data-v-x] h1[data-v-x] { ... }
div > .card { ... }  ->  div[data-v-x] > .card[data-v-x] { ... }
h1, .a { ... }       ->  h1[data-v-x], .a[data-v-x] { ... }

Declaration blocks are copied verbatim. @keyframes blocks keep their inner keyframe selectors (from/to/percent offsets) unscoped, while @media preludes pass through and only their inner style-rule selectors are scoped. Appending the attribute to every compound confines the rule to elements that all belong to this component — every element rendered from this component’s template is tagged with the same data-v-* attribute, so a rule like .header h1[data-v-*] could otherwise leak across component boundaries via an un-tagged ancestor.

CSS comments are replaced by a space before anything else happens (see [strip_css_comments]). Without that, a comment between two rules is glued onto the front of the next rule’s prelude, and the per-compound tokenizer then appends the scope attribute to the comment’s own */ as though it were a compound selector: .dark .app was emitted as [data-v-x] .dark[data-v-x] .app[data-v-x], a three-part descendant selector requiring a scope-tagged ancestor strictly above the .dark carrier. The carrier is the tree root, whose ancestor list is empty, so match_prefix finds no candidate and the rule can never match.