linkedin github twitter

CSS Variables 101

an interactive lesson

If you've never used CSS variables (AKA custom properties), you're in for a treat! They're easy to use, and they're so powerful that they may even change the way you work. Near the end of this lesson, you'll also have a chance to practice by styling this page with CSS variables.

So let's jump right in and create a CSS variable. You can declare a variable within :root, which will make it available to all elements on the page. The variable name always starts with two dashes:

:root { --primary-color: #fb3; }

Then, you can use the variable as a value for any property with the var() function:

.box { background-color: var(--primary-color); }

That's it! The result will look like this:

Just like with preprocessor variables, you can use CSS variables throughout your site to ensure different elements have consistent formatting.

But there's one big difference with CSS variables: You can change them at runtime.

Changing variables

Try resizing your browser below 700px. You should see the elements below change color:

Some
text

This is done by simply changing the variable with a media query:

@media all and (max-width: 700px) { :root { --primary-color: #47d; } }

So by changing the value of a single variable, many different elements can be restyled at once. Imagine how simple your media queries could be if you also used variables to control margins, text formatting, container sizes, grid properties, and more. In fact, Mike Riethmuller makes a case for using variables to handle almost all responsive design logic.

Variables cascade

You aren't limited to declaring variables in :root. You can declare (or modify) a variable anywhere, just like any property—in a container, card, hover state, and more. The variable's value will cascade down to all of the element's children.

For example, we could create an image gallery where the image height, width, size, and border radius use variables. If these variables are declared in :root, the gallery will use those values by default. However, we can also override the values within the .gallery class, in this case to zero out the border radius:

.gallery { --border-radius: 0; }

We can also create other variations of the gallery with modifier classes that set the variables to other values:

.gallery--dots { --block-size: 60px; --border-radius: 50%; }

In the new gallery, we'll use both the .gallery and .gallery--dots classes to get this result:

Note that we're able to make these changes by setting the variables in the container. We don't have to use child selectors (although we could if we wanted to) since the variables' new values will be passed down to the children. This makes modifier classes easier to create and manage.

This also means that our original .gallery class becomes a more generic template that we can modify and use in all kinds of situations. We can get a lot of mileage out of this class with basically no repetition.

Style this lesson!

Now that you know how to use CSS variables, you can experiment with an example: this very lesson. In the space below, try changing some of the values to style it however you want: