Scoped CSS not generating correctly
Version
3.0.0
Reproduction link
Repo: https://github.com/rymate1234/weird-vue-3-scoped-css-bug
Deployed: https://weird-vue-3-scoped-css-bug.vercel.app/
Steps to reproduce
- Run
yarn serve
- Open the website
- Observe the two elements using a custom
Button
component
What is expected?
As per the scoped css on the custom button component, both the link and the button should have the CSS background: crimson;
applied to them
What is actually happening?
This CSS is not applied to the element
This appears to have something to do with how the element gets assigned the selectors needed for scoped CSS to work.
On the deployed instance of the above repo, the button elements in the DOM get assigned the data attribute data-v-5b68cbbc-s
, however in the generated CSS the selector targets .button[data-v-5b68cbbc]
so something is causing Vue to generate mismatching selectors.
The new behavior is that, by default, scoped styles are not applied to the slots. You have to opt-in it via ::v-slotted
.
@leopiccionia I'm not trying to apply styles to a slot though, just the element that contains the slotted item?
Or am I misunderstanding?
Sorry, I mixed it.
::v-deep
can do the trick, then?
Notice in the RFC I previously linked that ::v-deep
syntax was changed since Vue 2.x.
I'm not targeting a child component, I'm targeting the element with class button that's inside the Button
component
Finally ran your repro.
The selectors are indeed not compiling correctly -- so ::v-slotted(.button)
actually makes the button crimson, but perhaps shouldn't.
It may be related to using a render function. Converting it to a non-functional component with a render
method doesn't solve it.
Converting the template to HTML, though, works correctly.
<component class="button" :is="href ? 'a' : 'button'" v-if="$slots.default">
<slot/>
</component>
This is because lost scope id information when create VNode using render function, so runtime will set slotted attribute data-v-13515282-s
, but button class has been compiled like follows:
.button[data-v-13515282] { background: crimson; }
.
Like @leopiccionia said, adding ::v-slotted(.button) or using template can make it work.
Using withScopeId
can also work. I create a sample code(https://codesandbox.io/s/render-lost-scope-id-8l8i2?file=/src/components/Button.vue), use stateful component but not functional component in order to add scope id.
Although it works, __scopeId
is internal property and I don’t know if this is officially recommended
I ran into a kind of similar problem, I posted my question in Vue Forum here. Is my approach is wrong or it is a bug?