Version
3.6.0-rc.2
Reproduction link
play.vuejs.org/
Steps to reproduce
When a <style scoped> rule has (1) a comma-separated selector list, where (2) one member uses :deep(), and (3) the rule contains nested child rules, the scope id ([data-v-xxx]) is not injected into the non-:deep() selectors in the list. Those selectors become unscoped and leak globally.
An example which triggers this bug:
.a,
.b :deep(.c) {
color: red;
> span { color: blue; }
}
What is expected?
.a[data-v-7ba5bd90],
.b[data-v-7ba5bd90] .c {
& {
color: red;
}
> span { color: blue;
}
}
What is actually happening?
.a is unscoped.
.a,
.b[data-v-7ba5bd90] .c {
& {
color: red;
}
> span { color: blue;
}
}
According to Claude, the problem seems to be caused as follows. Note that I did not verify this.
Root cause appears to be in rewriteSelector (packages/compiler-sfc/src/style/pluginScoped.ts): rule.__deep is tracked per-rule but set as a side effect while rewriting whichever member contains :deep(). When a nested rule is detected, the code sets shouldInject = rule.__deep and defers injection to a generated & { ... } wrapper. Because selectors are processed in source order, a plain selector processed before the :deep() member sees rule.__deep still unset (→ skips injection on itself), while the later & wrapper sees rule.__deep === true (→ also skips injection), so the scope id lands nowhere.
Version
3.6.0-rc.2
Reproduction link
play.vuejs.org/
Steps to reproduce
When a
<style scoped>rule has (1) a comma-separated selector list, where (2) one member uses:deep(), and (3) the rule contains nested child rules, the scope id ([data-v-xxx]) is not injected into the non-:deep()selectors in the list. Those selectors become unscoped and leak globally.An example which triggers this bug:
What is expected?
What is actually happening?
.ais unscoped.According to Claude, the problem seems to be caused as follows. Note that I did not verify this.