-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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
Nested components utilizing v-bind() in CSS improperly reference the CSS variable name of the parent node, causing undesired property inheritance in the child #12434
Comments
IMO the current repro is working as expected even you remove the default value The code references the CSS variable value is the stylesheet of the component (not component instance) so if we generate hash per instance, we'll have to generate a separate piece of CSS for each component instance to consume the value, which doesn't feel practical. And even we do this, the outcome is still the same as the repro because then you'll reference an undeclared CSS variable, which works the same way as right now. |
But after the fix at #12442, the |
But if you pass I think a better solution here, since If a non-falsy value is provided, then it should be used (e.g. Note You cannot set the value to Typically, you would want user-defined CSS custom properties to fall through (that is desirable) but in this particular case, the property is generated (meaning the child doesn’t know about its existence officially), and it’s improperly causing the child component to inherit the hashed variable value that it really shouldn’t be able to reference since the child component has its own prop binding, and therefore should respect its own default. |
After some thoughts and discussion with @adamdehaven, I think I agree with him the binding should be per component instance. Currently the inheritance is introduced by the way we are implementing it (via custom properties) instead of by design. I think I'd propose a practical fix for this: What about we produce |
This is my thinking as well; and seems more ideal (and actually desired) rather than using
|
Vue version
3.5.13
Link to minimal reproduction
Reproduction playground
Steps to reproduce
Block One
In
App.vue
we set thebackgroundColor
prop to a value oflightgray
.Inspect the rendered HTML of "Block One" and notice the value of the
background-color
prop is bound to the rootdiv
element via an inline CSS Custom Property, prefixed by a generated hash, e.g.style="--a4f2eed6-backgroundColor: lightgray;"
Notice the hash is also bound to the
data-v-a4f2eed6
attribute (for scoped styles) as well.Inspect the
Styles
panel in the browser, and notice the.block
class for "Block One" refers to the same CSS Custom Property for thebackground-color
property (prefixed in this example with--a4f2eed6-
)Block Two
App.vue
we do not set thebackgroundColor
prop for Block Two in the component props, meaning it utilizes the prop default value ofnull
(to prevent the property from being bound to the component since it is not desired for this instance)data-v-a4f2eed6
).Styles
panel in the browser, and notice the.block
class for "Block Two" refers to the same CSS Custom Property for thebackground-color
property (prefixed in this example with--a4f2eed6-
), rather than generating its own hash to attempt to use for the property.Block Three
What is expected?
"Block Two" (as referenced in the Steps to reproduce) should generate its own CSS custom property hash prefix (likely corresponding to the scoped styles hash as well) that is then utilized inside its style rule.
I would expect the generated CSS in the scenario described to evaluate to this:
What is actually happening?
Since instances of the same component share the same generated hash for both the scoped styles as well as generated CSS custom properties, the CSS
background-color
cannot be explicitly "unset" by providing anull
prop value for a secondary, nested instance of the same component.The result of this means that in order for the child component to not reference the CSS Custom Property of its parent, you have to explicitly set the default prop value that is mapped to v-bind to something that essentially "unsets" the value that may be present from the parent.
Using the example from the reproduction, to solve the issue, I would have to change the
defineProps
implementation to set thebackgroundColor
prop toinitial
(i.e. a reset), or alternatively pass a value of something liketransparent
which isn't ideal.This will then set the value of the same CSS Custom Property, on the child node, to
initial
System Info
No response
Any additional comments?
Generating a separate hash for each instance of a component (rather than reusing the same one for each one) would obviously lead to a lot of bloat in the injected DOM styles, especially for instances where this behavior doesn't exist.
I'm unsure if having to explicitly provide a "reset" value makes sense either, as it will bloat the inline
style
rules on every top-level component DOM element to set and/or reset the value.The text was updated successfully, but these errors were encountered: