Update CSS Variables on CSS Selectors With JavaScript

One of the most common ways you’ll see CSS variables demoed is by setting variables on the :root element. If you’re dealing with web components you can also set them on the :host.

:root {
    --primary-brand: red;
    --secondary-brand: blue;
}

/* In Web Components, this will target the web component element i.e. <my-custom-header></my-custom-header>*/
:host {
    --primary-brand: red;
}

Settings your variables on the :root is a great way to make sure that the variables are available to all elements. But it’s also possible to scope your variables to a selector.

For example we could change the --primary-brand variable for a theme class:

.cool-theme {
    --primary-brand: purple;
    --secondary-brand: yellow;
}

This is a great way to create themes with CSS variables but then fall back to variables set on the :root.

It’s also possible to update your CSS variables using JavaScript.

var root = document.documentElement;

root.style.setProperty('--primary-brand', 'red');

The article on CSS Tricks shows that this works for the :root, but does it work for variables that are scoped to another selector, such as .cool-theme? Yes! Similar to setting styles on the :root, we can grab any CSS selector with JavaScript and use the setProperty() method to update the variable.

var theme = document.querySelector('.cool-theme');

theme.style.setProperty('--primary-brand', 'yellow');

What’s cool about this is that you have the option of targetting the :root to make broad sweeping changes or you can target a selector, such as .cool-theme and isolate the variable changes to that selector.

Below is a simple CodePen showing this functionality in effect. Clicking the first button will update the --background variable on the :root and clicking the second button will toggle the .theme class which has it’s own --background variable set.