Dynamically set CSS properties in Vue
Theming simplifiedThe Problem
A client operating a SaaS service allows its tenants to define their own "theme" for the site by overriding CSS property values. After login the custom theme for the user is loaded into the application.
The current implementation leverages the :style
binding of Vue to generate the appropriate inline styles. As a result a lot of styling code is mixed into the templates.
What if we could style components with CSS classes and modify the properties of those classes instead?
The Solution: CSS Variables
In 2015 the W3C published the "CSS Custom Properties for Cascading Variables Module Level 1" specification. It describes how you can define custom properties: prefixed with two dashes. Elsewhere in you CSS you can refer to a property with the var()
method.
Define CSS variables
Suppose we define the following HTML & CSS. The default color of the header will be blue.
<h1 class="header">Header</h1>
:root {
--header-color: blue;
}
.header {
color: var(--header-color);
}
Change the value at runtime
To change the color of the header at runtime we can adjust the value of the CSS variable as follows:
document.body.style.setProperty('--header-color', 'red');
Due to CSS being reactive by design every change in a variable immediately cascades through the entire application.
Compatibility
Except for IE 11 all current browsers support CSS variables. If you really need to support IE11 you could use a polyfill: https://github.com/nuxodin/ie11CustomProperties.
For details see https://caniuse.com/#search=css%20variables.