-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
Scoped style attribute not attached to selector key if it's a pseudo-class/element #8868
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is as expected (align with the original behavior of div [data-v-7ba5bd90]:not(.test) {
color: tomato;
}
div[data-v-7ba5bd90] :not(.test) {
color: tomato;
} The above two rules are different. Whether we use scoped or not, we cannot change its original behavior. |
I understand that The two selectors
That may lead to problems because it allows styles to be applied to a tree that’s not part of the component's scope. In other words, |
I think this is a bug. The |
A few test cases for describe('SFC scoped CSS', () => {
test.each([
{
message: 'pseudo class with class',
source: `.foo:after { color: red; }`,
expected: `.foo:after[data-v-test] { color: red;`
},
{
message: 'bare pseudo class at root',
source: `:after { color: red; }`,
expected: `:after[data-v-test] { color: red;`
},
{
message: 'bare pseudo class as descendent',
source: `div :required { color: red; }`,
expected: `div :required[data-v-test] { color: red;`
},
{
message: 'pseudo class with tag as descendent',
source: `div input:required { color: red; }`,
expected: `div input:required[data-v-test] { color: red;`
},
{
message: ':not pseudo class',
source: `input:not(.error) { color: red; }`,
expected: `input:not(.error)[data-v-test] { color: red;`
},
])('$message', ({ source, expected }) => {
expect(compileScoped(source)).toMatch(expected)
})
}) Relevant code: core/packages/compiler-sfc/src/style/pluginScoped.ts Lines 173 to 175 in 069f838
I think the following change would fix this: - if (n.type !== 'pseudo' && n.type !== 'combinator') {
+ if (n.type !== 'combinator') { It comes with the caveat that the generated I'd be happy to contribute this if you want. I’m not totally sure if the approach is correct though. |
@kleinfreund |
Fix a scoped style leak when using pseudo classes caused by the scoped style attribute (i.e. `[data-v-...]`) not being attached to the key part of a selector when it contains pseudo class selectors. Closes vuejs#8868.
Fix a scoped style leak when using pseudo classes caused by the scoped style attribute (i.e. `[data-v-...]`) not being attached to the key part of a selector when it contains pseudo class selectors. Closes vuejs#8868.
Fix a scoped style leak when using pseudo classes caused by the scoped style attribute (i.e. `[data-v-...]`) not being attached to the key part of a selector when it contains pseudo class selectors. Closes vuejs#8868.
Uh oh!
There was an error while loading. Please reload this page.
Vue version
3.3.9
Link to minimal reproduction
https://play.vuejs.org example
Steps to reproduce
:is()
or:where()
) as the key (e.g.div :not(.test)
notdiv *:not(.test)
).Example:
What is expected?
The generated CSS rule set's selector list is scoped to the key of the selector (i.e.
div [data-v-7ba5bd90]:not(.test)
) even if the key is a bare pseudo-class or pseudo-element (except in the case of:deep
).What is actually happening?
The generated CSS rule set's selector list is scoped to the last selector part that is not a bare pseudo-class (i.e.
div[data-v-7ba5bd90] :not(.test)
).This leads to styles unintentionally leaking out of the scoped tree.
System Info
Any additional comments?
:is()
,:where()
, and the special case:deep()
The text was updated successfully, but these errors were encountered: