Subscribe to our Newsletter

Get articles, advice and tips about:

You can read more about our privacy policy and how we use your personal data here

CSS Variables or Custom Properties

CSS variables
or
Custom Properties

by Frida Nyvall

Variables in CSS. At first glance, this might not seem like a big deal as variables declared in SASS/SCSS have already been around for quite some time. Taking a closer look at the differences between CSS and SCSS variables, one begins to realize the power of CSS variables.

CSS variables vs SCSS variables

SCSS variables are static. Once they are processed and compiled, they are written in the CSS file and cannot be changed (except for by adding another style tag or CSS file that overwrites the first CSS file). The output of an SCSS variable is, in the end, a CSS declaration. To change the output of the variable, the SCSS file has to be processed and compiled yet again in a file build process.

CSS variables, on the other hand, are dynamic in that they can be changed and updated depending on context. CSS variables are affected by the cascade, can be targeted via CSS selectors and can be changed within media queries. A CSS variable can, therefore, depending on different circumstances hold multiple different values at the same time.

Just remember that the CSS variables are meant to be used for storing (and declaring) CSS properties, not just any data. For example, it is not possible to use them for declaring media query breakpoints. But don’t worry, using them inside of media queries is totally ok.

Support

Ok, so CSS properties are powerful, but what about browser support? caniuse.com shows that the most popular modern browsers including Edge (v16 and upwards) support the feature.

So basically CSS properties are ok to use unless you need to support Internet Explorer. In that case, you will need to write fallbacks.

Fallbacks

Adding fallbacks for non-supporting browsers can be done by declaring a fallback value that an older browser can process instead of the new and fancy variable.

.btn{
    color: green;
    --btn-color: green;
    color: var(--btn-color);
}

It is also possible to use the @supports declaration because browsers that support @supports also supports CSS properties. The declaration would look like this:

@supports(--css: variables) {
    /*code for browsers that support CSS Custom Properties*/
}

Where the variable name and value could be anything that is an accepted CSS property declaration.

I currently do not know of any working js polyfill that can be added to make CSS properties work everywhere (automagically).


Use Cases

Templating

The possibility to update a value once, and have it take effect in multiple places makes it easier both to keep code DRY and to maintain the codebase.

It is also possible to declare variables just on certain elements, and not globally on the :root. CSS variables are scoped within their respective set of {}, unless they are declared on the :root. If declared on the root (the HTML element), they are globally available.

Typical use cases are templating or theming. Example with three buttons with different color themes:

.btn{
    background-color: white;
    padding: 0.5em 1em;
    border: 0.125em solid black;
    color: black;
}

.btn-red{
    border-color: red;
    color: red;
}

.btn-blue{
    border-color: blue;
    color: blue;
}

Instead of repeating the border-color and color for .btn-blue and .btn-red, using CSS variables the code can become:

:root{
    --btn-color: black;
}

.btn{
    background-color: white;
    padding: 0.5em 1em;
    border: 0.125em solid var(--btn-color);
    color: var(--btn-color);
} 

.btn-red{
    --btn-color: red;
}

.btn-blue{
    --btn-color: blue;
}

If you wanted to keep the variable away from the global scope, you could do so by declaring it on the .btn:

.btn{
    --btn-color: black;
    color: var(--btn-color);
}

It is also possible to add fallback values, which is really useful. Fallbacks are declared like so: var(--btn-color, green). Which when added to the .btn class would make the color for elements with only the .btn class fall back to green.

.btn{
    background-color: white;
    padding: 0.5em 1em;
    border: 0.125em solid var(--btn-color, green);
    color: var(--btn-color, green);
}

Updating Styles at Certain Breakpoints

Another way CSS properties can help making style changes easier and more maintainable is using them with media queries.

Instead of making multiple changes to the CSS, it is possible to update just one variable that will take effect everywhere it is being used:

:root{
    --regular-fontsize: 1em;
}

p{
    font-size: var(--regular-fontsize);
    margin: var(--regular-fontsize) 0;
}
/*imagine the var --regular-fontsize is used throughout the website*/

@media screen and (min-width: 30em) {
/*it can then be conveniently changed everywhere at once by updating the value inside a media query.*/
    :root{
        --regular-fontsize: 1.25em;
    }
}

Using calc to Supercharge CSS Properties

It is when CSS variables are used in calc expressions perhaps the most impressive results are produced. In the blog post “Responsive Typography with CSS Custom Properties (CSS Variables)”, I’m doing a deep dive in how to achieve true responsive typography (that continuously dynamically scales with window width) using calc() together with CSS variables.

CSS variables can be declared unitless. Add whatever unit you need by multiplying it with the variable in a calc() expression. Leveraging this, CSS variables and calc() allow us to write more dynamic code – just using CSS:

:root{
    --modular-scale: 1.125;
}

p{
    font-size: calc(var(--modular-scale) * 1em);
}

h6{
    font-size: calc(var(--modular-scale) * var(--modular-scale)* 1em);
}

@media screen and (min-width: 60em) {
    :root{
        --modular-scale:1.3333;
    }
}

With JS and Dynamic Inputs

If what can be achieved with CSS variables alone is amazing, adding JS to the receipt further expands the horizon. By attaching some sort of user input to CSS variables that updates or changes them, some really fun effects can be achieved.

Popular things to change are color values, font-sizes, and widths as seen on multiple examples in Chris Coyier’s article “CSS Custom Properties and Theming” on CSS Tricks.

But there are also other properties that produce useful effects when changed, such as blurring an image with filter effects as demonstrated by Wes Bos on day 3 of his excellent JavaScript30 series.

Another great example of making use of CSS properties is what Dave Rupert named the “Cheapass Parallax Effect”, which creates a lightweight parallax effect by changing opacity and transform when the user scrolls down.

Boosting Animations

Being able to use this type of dynamic values is a great advantage when it comes to creating animations on the web. But CSS properties can also help achieving better performance in animations, by leveraging their capability of affecting multiple elements that share the same variable. This goes for both pure CSS animations, as well as those also using JS.

For example, when animating with JS: Instead of updating an inline style on every element each time a value need to change, a CSS variable can be set to just update an inline style on the root element.

Resources

Tags

More posts

img

All about webP images

img

CSS Special Effects

img

CSS Filters