Dynamically set CSS properties in Vue

Theming simplified
author's avatar
Kees de Kooter
Jul 8 2020 17:56 • 1 min read

The 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.