CSS Custom Properties—Dynamic Changes With And Without Javascript

Have you ever wished you could change the value of a Sass or Less variable after your page has loaded? I have. Unfortunately, it’s not something you can do as the variables cease to be variables once the preprocessed code is compiled into CSS. You don’t have the same limitation with CSS custom properties.

I’ve been talking about custom properties for a few weeks now. I began by showing you how to define and use them and then offered some simple examples to make your code more readable and to help with contextual styling. Last week I showed you how you can work with custom properties inside @media queries.

At the start of this series I mentioned that one of the major advantages of custom properties is their dynamic nature. Where preprocessor variables are turned into fixed values on compile, custom properties can change their values after a page has loaded.

I touched on this dynamic ability last week when talking about @media queries. Today I want to continue and look at how we can make changes through user interaction and Javascript.

Changing CSS Custom Properties Without Javascript

While most of the dynamic magic will require a little bit of Javascript, let’s start with a simple example and change the value of a custom property on :hover. Know that this will work on any pseudo class and not only :hover

Here’s how we might change the background color of divs using custom properties. I added some CSS to define a width and height and defined a custom property –background with a value of #ccc. I then set the background-color property using the var() function and gave it a transition of 1s just because.

1
2
3
4
5
6
7
8
div {
 width: 15em;
 height: 15em;

  --background: #ccc;
  background-color: var(--background);
  transition: background-color 1s;
}

To change the background color I redefined the custom property on the :hover pseudo class and assigned it a new value of #cce.

1
2
3
div:hover {
  --background: #cce;
}

Realistically we could have done this without the use of custom properties by changing the background-color property directly or even with the use of preprocessor variables.

It’s a fair point, particularly with an example as simple as this one, but imagine you’re changing more than the background color. Maybe you want to change background color, text color, and various font properties. You still wouldn’t need custom properties, but as we saw the last couple of weeks this method can result in cleaner and more readable code.

Changing CSS Custom Properties With Javascript

Where things get really interesting is when we use Javascript to change the values of custom properties.

There are two things we need to be able to do to use Javascript with custom properties. We need to know how to get the value of a custom property and also how to set a new value on a custom property.

Get the Value of a Custom Property

To read the value you use two Javascript functions, window.getComputedStyle and getPropertyValue. The former method will get every computed CSS property and value of every element and the latter method can be used to get the value of specific properties.

1
2
var style = window.getComputedStyle(element[, pseudoElt]);
var value = style.getPropertyValue(property);

If you work with Javascript, this is probably nothing new. However, if you aren’t familiar with Javascript, you might like an example. Here’s a little CSS where I defined a –color custom property inside :root and assigned it a value of red.

1
2
3
:root {
 --color: red
}

We’ll use the getComputedStyle() and getPropertyValue() methods to read the value of –color. The first line of Javascript below gets all the styles of document.documentElement (the way to reference :root) and assigns the result to the Javascript variable, styles.

The second line gets the specific value for the –color custom property defined in :root and assigns that value to a new variable colorValue. In this case –color is the only property, but in practice there would likely be others.

1
2
var styles = getComputedStyle(document.documentElement);
var colorValue = styles.getPropertyValue('--color');

The variable colorValue should now hold a value of red, which is the value I initially set on –color in the CSS. To proves this to yourself you can use the alert() function to show the value on your screen.

1
alert(colorValue);

Set the Value of a Custom Property

To set a new value on a custom property you use the style.setProperty method.

1
style.setProperty(propertyName, value, priority);

Note that setProperty can take three parameters. The first two are necessary as they identify the property to change and the new value it will be assigned. The third parameter, priority, is optional and allows you to set !important, though as a general rule you don’t want to do this.

Technically the value parameter is also optional and if you leave it out, it will be treated as an empty string. Most of the time you’ll want to set a value, but leaving it out is a way to change the custom property to an empty string.

It’s easier to set a new value than to read the existing one as we don’t need to hold anything temporarily in a variable. Again document.documentElement is the :root so this line of code changes the value of the :root custom property –color to green.

1
document.documentElement.style.setProperty('--color', 'green');

In fact, the property doesn’t even need to exist before setting a new value. You could set the custom property initially inside a setProperty method, if you’d like.

Remove the Value of a Custom Property

There’s also a removeProperty() function to remove the entire property and its value. If for some reason you want to remove the –color custom property, you could do this.

1
document.documentElement.style.removeProperty('--color');

Together getPropertyValue, setProperty, and removeProperty offer a lot of options for changing custom properties on the fly.

Changing Color Values with a Color Picker

Now that we’ve seen how to get and set the values of custom properties, as well as how to remove the property entirely, let’s try an example showing how you might use this information in practice. Again, I’ll keep the example as simple as possible for the sake of explanation.

Here I created an empty div and an input with a type of color so users can access their default color picker. We want to let users select a color and then have their selection become the background color for the div.

1
2
<div></div>
<input type="color" id="div-bkgd" value="#cccccc">

The CSS is simple as well. I created a custom property (–background) inside the :root and assigned it a value of #ccc. I gave the div a width and height and using the var() function set its background color to the value of the –background custom property. I also centered the div using auto left and right margins.

I then set the input to display as a block level element, gave it a width, and also used auto margins to center it. None of this is necessary, but I think it makes for a more presentable example.

The important part for this example is the custom property.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
:root {
 --background: #ccc;
}

div {
 width: 20em;
 height: 20em;
 margin: 1em auto;
 background: var(--background);
}

input {
 display: block;
 width: 10em;
 margin: 1em auto;
}

Now for the Javascript. First we need to grab a hook to the color input. I used the document.querySelector method, which matches the specified selector, in this case the element with an id of div-bkgd, which is the input element. I assigned the value to a variable called colorInput.

Next I added an event listener to colorInput, which will listen for any change to the color input and then run a function. The function uses setProperty to redefine the –background custom property with the new color value.

1
2
3
4
5
var colorInput = document.querySelector("#div-bkgd");

colorInput.addEventListener("change", function() {
 document.documentElement.style.setProperty("--background", this.value);
});

Here’s a demo I set up so you can see this in action. Select a color from the color picker and the background color of the div should change to your selection.

Note: The color input doesn’t yet have universal support. It doesn’t work in IE or any version of Safari, though the latter should let you type in a hex color as opposed to letting you choose one from a color picker.

I also added another type of input (the range input) to the demo to allow you to control the font-size of some text I added inside the div. The code is very similar to how I changed the background color here. The main difference (aside from the different type of input) is that you have to append the units to the font-size.

I also made a few tweaks in the demo to set dimensions in terms of rem units instead of em units so that the divs don’t change size as you adjust the font-size.

Additional Examples

Because I kept the examples on the simpler side, I want to point you to a few that are a little more complex so you can see more of the power of custom properties when combined with Javascript.

Here are three examples that use sliders and color pickers to alter the values of custom properties. They all use similar techniques to the demo I created, though each does so in greater detail.

You’ll notice the last link mentions theme previews. Theming crops up often in articles and examples featuring CSS custom properties. Here are a couple of demos showing what you can do.

And here are some articles walking you through the process of theming a site.

Closing Thoughts

Combining CSS custom properties with Javascript or another scripting language really shows off what custom properties can do. And if Javascript isn’t your thing, know that there isn’t a lot you have to learn in order to get, set, and remove values and properties. You can even copy the code here and update it with the name of your particular custom property.

If you prefer to stay away from Javascript entirely, you can still update CSS variables through the usual pseudo selectors like :hover, :visited, :first-child, :nth-child, etc.), though I’d suggest it’s worth taking the time to learn the little bit of Javascript, since you can do so much more with it.

Next week I want to wrap up this series showing you how to combine custom properties with transforms, transitions, and keyframe animation.

Download a free sample from my book, Design Fundamentals.

Leave a Reply

Your email address will not be published. Required fields are marked *