Getting started with CSS Custom Properties

Custom properties in CSS are exceptionally useful, not just for tokenising your CSS, but also for abstracting complexity and interactivity into smaller, easier to manage pieces. This short guide will get you up to speed with how they work and how to use them.


Say you’ve got some CSS like this:

h1 {
  background: goldenrod;
}

p {
  color: goldenrod;
}

.my-element {
  border: 1px dotted goldenrod;
}

There’s a lot of repetition in there, but how do you improve that with native CSS? You can use CSS Custom Properties—also known as CSS variables—to abstract and tokenise your CSS to make your code more manageable.

:root {
  --primary: goldenrod;
}

h1 {
  background: var(--primary);
}

p {
  color: var(--primary);
}

.my-element {
  border: 1px dotted var(--primary);
}

In this tutorial, we’re going to get a grip of the basics of custom properties and learn some of the extremely cool and helpful stuff they can do and how they can help your projects.

The basics

Let’s start right from the top and look at some basics. A custom property is just like a normal CSS property and value pair: a declaration. These declarations are defined inside a CSS rule.

:root {
  --text-color: rebeccapurple;
}

Once a custom property is defined, you can grab the value of it, using the var() function. This will retrieve the current computed value of the property, which we’ll cover in more detail, later in this tutorial.

With the combination of a declared custom property and the var() function, we can use them in our CSS to apply values, like this:

:root {
  --text-color: rebeccapurple;
}

h1 {
  color: var(--text-color);
}

Fallbacks

If a custom property value that hasn’t been defined, the initial or inherited value will be used instead, but if the Custom Property is invalid and you don’t provide a fallback, it’ll fail. This can result in some pretty lousy looking user interfaces, so a good shout is to provide a fallback to the var() function.

h1 {
  color: var(--text-color, royalblue);
}

By passing a second, fallback value, the <h1> will be royalblue if the --text-color custom property has not been defined.

Fallbacks are handy as heck, but they aren’t used by browsers that don’t support custom properties. For the microscopic share of browsers that don’t support custom properties, you can use custom properties as a progressive enhancement, like this.

h1 {
	color: royalblue;
  color: var(--text-color, royalblue);
}

We still have to pass a fallback to the var() function because as we just learned, an invalid value—which includes undefined custom properties—will result in the initial or inherited value being used.

Custom properties are computed

Once you set a value for a custom property, it can be changed in context and just like any other declaration—a property and value pair—it will be affected by specificity and the cascade.

Take the first example as a context:

:root {
  --text-color: rebeccapurple;
}

h1 {
  color: var(--text-color);
}

If this <h1> was inside an <article> with a class of .colour-change, which has a CSS rule, declaring a value for --text-color: that value would be applied.

:root {
  --text-color: rebeccapurple;
}

h1 {
  color: var(--text-color);
}

article.colour-change {
  --text-color: seagreen;
}

This CSS is applied because .article.colour-change has a higher specificity than :root.

You can set custom properties with JavaScript

This ability to contextually override a custom property makes them incredibly useful for interactive states and generally writing less CSS. The previous demo used a toggled CSS class to contextually set a custom property value, but you can also set them inside your JavaScript:

const article = document.querySelector('article');
const button = document.querySelector('button');

button.addEventListener('click', (evt) => {
  article.style.setProperty('--text-color', 'tomato');
});

The <article> gets the value for --text-color applied in its style attribute, which gives it a way higher specificity than :root.

Wrapping up

This quick intro to Custom Properties has hopefully given you the knowledge and confidence to explore them further. If you want to learn more about them, I recommend the following resources:

Until next time, take it easy 👋


👋 Hello, I’m Andy and this is my little home on the web.

I’m the founder of Set Studio, a creative agency that specialises in building stunning websites that work for everyone and Piccalilli, a publication that will level you up as a front-end developer.


Back to blog