What You Should Know About CSS Variables

The time has finally come, CSS is about to become dynamic with the introduction of CSS variables. While the new technology is experimental, it’s very exciting for me as it could mean less compiling in my current Sass-based CSS workflow.

This article introduces the awesome new technology as well as gives you some examples of CSS variables in practice.

CSS variables by definition

According to MDN, “CSS variables are entities defined by CSS authors which contain specific values to be reused thoughout a document. They are set using a notation (e.g. --main-color: black;and are accessed using the var() function (e.g. color: var(--main-color;).”

If you’re familiar with variables inside your LESS and Sass-based documents this concept is not so new, but the beauty behind this new technology is that you don’t have to use some sort of compiler (Grunt, Gulp, Codekit, etc…) to get your CSS to work correctly.

Why variables anyway?

Traditional CSS is written in a very repetitive fashion. Often times you need to use a series of selectors to traverse your web page and apply styles to the element of your choosing. The old way looks like this:


.content {
  background-brown: brown;
  color: white;
  font-size: 1rem;
}
.sidebar {
  background-color: brown;
  color: white;
  font-size: 1rem;
}
.hero {
  background-color: blue;
  color: white;
    font-size: 2rem;
}

Here I have repeated a few styles. There’s nothing wrong with this code. It’s just very repetitive. So rather than typing things over and over, variables are here to help you define specific parameters of which you can use throughout your entire stylesheet. This both makes it easier to type and easier to update later.
.
The benefits are massive as your stylesheet grows longer for larger websites and applications. Variables allow you to make changes easily across many different style definitions and be more consistent with your property definitions (e.g. rather than have 20 different versions of blue you will just reuse the same as defined in a variable).

The basics

Declaring a variable:


.header {
  --header-bg-color: blue;
}

Using the variable:


.header {
  background-color: var(--header-bg-color);
}

Putting it to practice in the real world

Say you are building a website with different header styles for different types of pages. In the example, below I’ve defined some basic HTML to illustrate this.


<!-- Home Page-->
<html>
    <body class="home">
    <header class="header"></header>
        ...
    <body>
</html>

<!-- Random Page with Body class of .page-->
<html>
    <body class="page page-about">
    <header class="header"></header>
        ...
    <body>
</html>

The HTML is for two pages. One being a home page and the other a basic repeated page on the website.

In our stylesheet we go about using CSS variables like this:


:root {
  --header-home-bg-color: blue;
  --header-pages-bg-color: white;
}

.home .header {
  background-color: var(--header-home-bg-color);
}

.page .header {
  background-color: var(--header-pages-bg-color);
}

You may notice the :root pseudo-class a the top. Rather than declaring a variable inside of an element you can do so for the entire stylesheet in this manner.

Cascading effect

When defining and using variables, the same cascading rules apply for the traditional CSS.


:root { --color: black; }
div {
    --color: green;
}
.notice {
    --color:red;
}

<p>This paragraph will be black because of the root element.</p>
<div>This div was set to green but only it was</div>
<div class="notice">
    This div is set to red directly.
    <p>This paragraph is also set to red</p>
</div>

Taking advantage of the cascading nature means you can go as far as creating custom properties for responsive design.


:root {
  --main-margin: 10px;
}
div {
  margin: var(--main-margin);
}

@media(min-width: 767px) {
  : root {
    --main-margin: 5px;
  }
}

Today’s CSS preprocessors make the above code impossible. Something as illustrated above is only available using CSS variables. A lot of potential here.

The var() function explained

Using the var() function is required to retrieve the custom property you have defined. It accepts two parameters, one being an array of multiple sub-parameters.

 var(--variable-name [, <declaration-value> ]? ) 

By now, I hope the --variable-name property makes sense as it represents the variable itself. The <declaration-value> is a fallback value used when the variable is invalid. These values can be a comma-separated list of font names for instance. Another example demonstrates a shorthand series of padding definitions: var(--containerpadding, 10px 15px 20px 30px). Note that these shorthand values are not comma separated.
Here’s an example with fonts:


:root {
  --font-stack: "Open Sans";
}
body {
  font-family: var(--font-stack, "Helvetica", "Arial");
} 

And another with shorthand properties:


:root {
  --base-pad: 10px 20px 30px;
}

.article {
  padding: var(--base-pad, 10px 10px 10px);
} 

Integrating with JavaScript

Getting the value of a custom property can happen by using the getPropertyValue() method or you can set properties directly like below.


<style>
/* CSS */
:root {
  --brand-primary: blue;
  --brand-secondary: green;
}

.logo {
  color: var(--primary-color);
}
</style>

<!--HTML-->
<div class="header">
    <a class="logo">My Brand</a>
</div>

<!--JS-->
<script>
const logoColor = document.querySelector('logo').style.setPropery('--brand-primary', 'var(--brand-secondary)');
</script>

Browser Support

This is all still experimental technology so I would advise against using it in production environments, but you can check the status updates here or here.

Chrome 49, Firefox 42, Safari 9.1, and iOS Safari 9.3 support some custom properties.

Now that we explored what CSS variables are, I hope you will go have some fun with them. Coming from Sass or Less myself I found this technology to pretty quick to learn though there are some new features you wouldn’t normally get out of the box with Sass or Less. Inheritance and cascading effects in particular, should be used wisely.

If CSS variables interest you check out a past article called Advanced CSS Selectors you never knew about. Happy hacking!