Star selectors leak scoped styles into children #12906
Labels
🔨 p3-minor-bug
Priority 3: this fixes a bug, but is an edge case that only affects very specific usage.
scope: sfc
Vue version
3.5.13
Link to minimal reproduction
https://play.vuejs.org/#eNqNUtFOwjAU/ZWmLyQGNwn6gpNEDSb6oEZ8bGLmeoFi1zZtN2YI/+5t5wAjGt52zz09O/fes6bXxiR1BXREM1dYYTxx4CszZkqURltPbnVpyMzqkvSSNBSB3rtkKkvbB0jFwkNpZO4BK0IyLmpSyNy5K0ZXesVohLERBNLfRZbiC/zK0j0dLJ3/lEBcoQ3wSExQjZyMZsI6f1oshORk3aq9a8vBjsjANMRpKTixwNEmIZvoNSiNaZ96VFMzMU+WTiscOz5ntEAvQoJ9Ml5o5RgddcKM5lLq1UPEvK2g3+HFAoqPA/jSNQFj9NmCA1sDo9uez+0cfNueTB+hwe9ts9S8ksj+p/kCOFwVPLa0m0pxtL3Hi27v4/GEmr+6SeNBuW6oYDQuJfIZxWOGM/w1+s7uMDn/XuYGt9gF4UBujs2FUCr47sIQAnAXztplYYtOAS/Gd/CRYUniD9pRTM45LgPTcWYaDMXPSLzVYMOCcJhhcpEMhnTzBXDwBpE=
Steps to reproduce
Foo
class="foo"
on the root element.foo * { border: 1px solid red; }
Bar
<bar/>
into Foo's rootWhat is expected?
The star selector should be scoped to inside
Foo
What is actually happening?
The star selector isn't being scoped, which causes the styles to leak into child elements
System Info
Any additional comments?
The example provided includes a
:first-child
pseudo-class, which makes the behavior (and use case) a bit clearer, however the scoping issues occur regardless of whether the pseudo-class is specified.We ran into this issue while attempting to upgrade from Vue 2 to Vue 3, where certain selectors that used to be scoped to immediate children were suddenly applying to deep children. The usage sites themselves were flawed in other ways, and should have been using direct child combinators, but those are workarounds and shouldn't be necessary for scoping to apply correctly.
In the past Vue 3 used to mirror Vue 2's behavior, which scopes only the star selector. (Vue 2 demo). That behavior itself isn't ideal, which was reported in #10548 and then addressed in #10551, however in doing so it caused the styles to leak to children instead of from parents. More manageable, but still not ideal.
Here's a sample of different selectors and how they compile in Vue 2 vs Vue 3 (
[--]
represents the scoping attribute selector)The solution for this would be to scope both the final class selector and the star selector:
Ideally the bare pseudo-class (
.foo :first-child
) would be fully scoped too, but if the goal is parity with Vue 2, that's not necessary.Also the ticket that started this, #10548, isn't actually running into a fundamental scoping issue caused by star selectors. The same thing applies to any non-direct-child combinators (demo), but in their case the star selector made it difficult to manage. The only way to solve the fundamental scoping issue would be to add the scope attribute to every level of the selector (
.foo .bar :first-child
->.foo[--] .bar[--] [--]:first-child
), but I'm guessing that has an adverse performance impact, otherwise it likely would have done that from the start.The text was updated successfully, but these errors were encountered: