-
Notifications
You must be signed in to change notification settings - Fork 546
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
SFC state driven CSS variables (<style vars>) #226
Conversation
- use `vars` instead of `:vars` - default all variables to local in scoped + vars mode - remove expression syntax restrictions
This RFC is now in final comments stage (prior discussion and feedback in #182). An RFC in final comments stage means that: The core team has reviewed the feedback and reached consensus about the general direction of the RFC and believe that this RFC is a worthwhile addition to the framework. |
<style scoped vars="{ color }">
h1 {
color: var(--color);
font-size: var(--global:fontSize);
}
</style> What is the reason to make all variables local if there is list of variables to bind? Why not make local only ones that are in |
Good question. Consider the case where a non-var'd CSS variable is declared within the scoped style tags. If it's not scoped, it will leak out into the global scope and affect child styles using the same var name: <style scoped vars="{ color }">
h1 {
--fontSize: 12px; /* ⬅ If this is not scoped, it will cascade down and affect children */
color: var(--color);
font-size: var(--fontSize);
}
</style> Similarly, unused classnames in a SFC are also scoped because it might match against something outside of the SFC and cause a collision. |
Why not auto import variables by their usage? |
I think scoping declared variables should not even be a part of this RFC. And in this example variable will not leak out into global scope because My issue with current approach is that adding You can use global classes in My suggestion is to use |
@Asv1 unlike JavaScript variables, CSS variables may be referencing something defined outside of the component. Without explicit variable passing the scoping will become ambiguous. @Demivan the So the trade-off is either limit <script setup>
import { inject } from 'vue'
const themeVars = inject('theme-variables')
</script>
<style vars="themeVars">
/* use injected variables from theme */
</style> |
@yyx990803 Thanks for explanation. <style scoped vars="themeVars">
h1 {
color: var(--bind:color); // or --var:color
font-size: var(--fontSize);
}
</style> But what is preferable probably depends on a project. If project does not use global variables automatic prefixing would be more convenient. Maybe option to switch this behavior could be added as |
@yyx990803 |
If I'm understanding the problem correctly, I think hashing can be moved to run-time and eliminate the need for the Given the SFC: <style vars="{ textColor }">
.class {
color: var(--text-color);
}
</style> vue-loader compiles this to: function compileStyles(vars) {
return `
.class{
color: var(--${vars.textColor}); // could be '--text-color' or '--HASH-text-color'
}
`;
} There's probably some overhead I'm not thinking of though. I'm not sure if the theme-injection code-snippet reacts to every Interesting use-case by the way. I didn't think If the following syntax can be supported <style vars="somePropertyOnVM">
.class {
color: var(--somePropertyOnVM.textColor);
font-size: var(--someGlobalVar);
}
</style> Supporting object paths could be beneficial as well since theme objects can be nested for organizational purposes: {
colors: {
primary: "red",
...
},
...
} <style vars="themeVars">
.class {
color: var(--themeVars.colors.primary);
}
</style> |
Thanks for the feedback - this actually made me rethink the proposal and identified a number of issues that can be improved. A new version of this feature is proposed in #231. |
This is previously part of #182 - but moved into a separate PR so that it can advance on its own.
Rendered