Often, it's desirable for a component to expose properties the caller can use to customize the style. But if these take arbitrary values rather than just, say, class names, the child component then must use style
attributes to apply the values. Unfortunately, this litters the <template>
markup with style information. Also, the style
attribute cannot be used to assign CSS properties to pseudo-elements like :hover
and :before
, which significantly limits the properties a component can expose to the caller for custom styling.
The only workaround is for the parent's CSS to override the child's CSS, but that requires the parent's CSS to be coupled to the child's implementing markup. The same value (or variants based on it, such as lighter or darker shades of a color) may be used in a number of selectors, complicating this effort, and if the component uses scoped CSS or highly-specific selectors, it may be even more difficult to override.
CSS variables are now fully supported by every common browser other than IE11. So, I'm proposing that Vue support mustache syntax in the <style>
block of SFCs where CSS variables are declared, and that Vue set and react to changes to these values by using the DOM's style.setProperty
method.
This will allow component authors to provide props for more styling decisions, in a way that is still as reactive as using the style
attribute, but with more capabilities (for pseudo-elements) and a tidier template. Internally, components can also use this to make styling decisions, including for pseudo-elements, based on computed values, all fully reactive.
Here's an example of a component that does support CSS variables as properties, but has to wire it up manually with a watcher:
https://github.com/richardtallent/vue-stars/blob/master/src/VueStars.vue
It may be possible to support IE <= 11 by replacing variables in the style with values and replacing the generated style tag as needed.
The API would simply be that the ```