It’s Time To Start Using CSS Custom Properties

Today, CSS preprocessors are a standard for web development. One of the main advantages of preprocessors is that they enable you to use variables. This helps you to avoid copying and pasting code, and it simplifies development and refactoring.

We use preprocessors to store colors, font preferences, layout details — mostly everything we use in CSS.

But preprocessor variables have some limitations:

  1. 1) You cannot change them dynamically.
  2. 2) They are not aware of the DOM’s structure.
  3. 3) They cannot be read or changed from JavaScript.

As a silver bullet for these and other problems, the community invented CSS custom properties. Essentially, these look and work like CSS variables, and the way they work is reflected in their name.

Custom properties are opening new horizons for web development.

Syntax to Declare And Use Custom Properties

It starts with a reserved symbol — for example, $ in Sass and @ in LESS.

CSS custom properties have gone the same way and use — to introduce a declaration. But the good thing here is that you can learn this syntax once and reuse it across browsers!

For Ex:-  to declare a variable instead of a usual CSS property such as color or padding, just provide a custom-named property that starts with    :


  –box-color: #4d4e53;

  –box-padding: 0 10px;


Here are examples of valid custom properties:


  –main-color: #4d4e53;

  –main-bg: rgb(255, 255, 255);

  –logo-border-color: rebeccapurple;


  –header-height: 68px;

  –content-padding: 10px 20px;


  –base-line-height: 1.428571429;

  –transition-duration: .35s;

  –external-link: “external link”;

  –margin-top: calc(2vh + 20px);


  /* Valid CSS custom properties can be reused later in, say, JavaScript. */

  –foo: if(x > 5) this.width = 10;


As with other CSS properties, custom ones cascade in the same way and are dynamic. This means they can be changed at any moment and the change is processed accordingly by the browser.

To use a variable, you have to use the var() CSS function and provide the name of the property inside:



  –box-padding: 0 10px;

  padding: var(–box-padding);


.box div{

  color: var(–box-color);



The var() function is a handy way to provide a default value. You might do this if you are not sure whether a custom property has been defined and want to provide a value to be used as a fallback. This can be done easily by passing the second parameter to the function:



  –box-padding: 0 10px;


  /* 10px is used because –box-margin is not defined. */

  margin: var(–box-margin, 10px);


How To Start Using Them

According to a recent survey, Sass continues to be the preprocessor of choice for the development community.

So, let’s consider ways to start using CSS custom properties or to prepare for them using Sass.

We have a few options.


One advantage of this method of manually checking in the code whether custom properties are supported is that it works and we can do it right now (don’t forget that we have switched to Sass):

$color: red;:root {  –color: red;} .box {  @supports ( (–a: 0)) {    color: var(–color);  }  @supports ( not (–a: 0)) {    color: $color;  }}

This method does have many cons, not least of which are that the code gets complicated, and copying and pasting become quite hard to maintain.


The PostCSS ecosystem provides dozens of plugins today. A couple of them process custom properties (inline values) in the resulting CSS output and make them work, assuming you provide only global variables (i.e. you only declare or change CSS custom properties inside the :root selector(s)), so their values can be easily inlined.

An example is postcss-custom-properties.

This plugin offers several pros: It makes the syntax work; it is compatible with all of PostCSS’ infrastructure; and it doesn’t require much configuration.

There are cons, however. The plugin requires you to use CSS custom properties, so you don’t have a path to prepare your project for a switch from Sass variables. Also, you won’t have much control over the transformation, because it’s done after the Sass is compiled to CSS. Finally, the plugin doesn’t provide much debugging information.


I started using CSS custom properties in most of my projects and have tried many strategies:

  • 1) Switch from Sass to PostCSS with cssnext.
  • 2) Switch from Sass variables to pure CSS custom properties.
  • 3) Use CSS variables in Sass to detect whether they are supported.

As a result of that experience, I started looking for a solution that would satisfy my criteria:

  • 1) It should be easy to start using with Sass.
  • 2) It should be straightforward to use, and the syntax must be as close to native CSS custom properties as possible.
  • 3) Switching the CSS output from the inlined values to the CSS variables should be easy.
  • 4) A team member who is familiar with CSS custom properties would be able to use the solution.
  • 5) There should be a way to have debugging information about edge cases in the usage of variables.

As a result, I created css-vars, a Sass mixin that you can find on Github. Using it, you can sort of start using CSS custom properties syntax.

Using css-vars Mixin

To declare variable(s), use the mixin as follows:

$white-color: #fff;$base-font-size: 10px; @include css-vars((  –main-color: #000,  –main-bg: $white-color,  –main-font-size: 1.5*$base-font-size,  –padding-top: calc(2vh + 20px)));

To use these variables, use the var() function:

body {  color: var(–main-color);  background: var(–main-bg, #f00);  font-size: var(–main-font-size);  padding: var(–padding-top) 0 10px;}

This gives you a way to control all of the CSS output from one place (from Sass) and start getting familiar with the syntax. Plus, you can reuse Sass variables and logic with the mixin.

When all of the browsers you want to support work with CSS variables, then all you have to do is add this:

$css-vars-use-native: true;

Instead of aligning the variable properties in the resulting CSS, the mixin will start registering custom properties, and the var() instances will go to the resulting CSS without any transformations. This means you’ll have fully switched to CSS custom properties and will have all of the advantages we discussed.

If you want to turn on the useful debugging information, add the following:

$css-vars-debug-log: true;

This will give you:

  • 1) a log when a variable was not assigned but was used;
  • 2) a log when a variable is reassigned;
  • 3) information when a variable is not defined but a default value gets passed that is used instead.



Now you know more about CSS custom properties, including their syntax, their advantages and good usage examples.

You have learned how to detect whether they are supported, how they are different from CSS preprocessor variables, and how to start using native CSS variables until they are supported across browsers.

This is the right time to start using CSS custom properties and to prepare for their native support in browsers.


Leave a Reply

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