Tiffany B. Brown

11 August 2017

CSS Variables For Fun and Profit

The idea of CSS variables has long been bandied about in web circles. Eventually it found its way into our workflows with pre-processors like Sass and Less. Now, however, variables are part of standard CSS thanks to the CSS Custom Properties for Cascading Variables Module Level 1 specification. They're widely supported, but use a fallback for the benefit of Internet Explorer 11 or Microsoft Edge 14 users. Neither browser currently supports them.

Microsoft Edge 15+ supports custom properties, but the implementation is still a bit buggy. Animating between custom properties, in particular, may cause Edge to crash. Microsoft has fixed the bug, but the fix hasn't made its way into a release just yet.

Defining a variable

To define a variable, decide on a property name and prefix it with two hyphens.

--primarycolor: #0ad0f9ff;

Most alphanumeric characters, along with hyphens and underscores are permitted in property names. Emoji are also valid in names: --😍: #dd0000 works.

The -- tells the CSS parser that this is a custom property. When used as a variable, the value of a custom property becomes the replacement value.

Custom property names are case sensitive. Parsers treat --primarycolor and --primaryColor as two different properties. That's a pretty significant change for CSS, in which most properties and values are case insensitive.

As with standard CSS properties, custom properties need to be placed within a declaration block. One emerging pattern is to define custom properties within a :root ruleset.

:root {
    --primarycolor: #0ad0f9ff;
}

The :root pseudo-class refers to the root element of a document. For HTML documents, that's the html element. For SVG documents, it's the svg element. Using :root makes the property globally available and inheritable.

Using a variable

To use our custom property as a variable, we'll need the var() function.

.logo:hover path {
    fill: var(--primarycolor);
}

var() indicates to the CSS parser that it should use the value of --primarycolor as the value for the fill property. Hover over the logo below to see this in action.

Setting a fallback value

var() actually accepts two arguments: the custom property and a fallback value.

.button--switch {
    background-color: var(--button-default, #636);
}

If --button-default hasn't been defined, the CSS parser will use the fallback value (#636). Toggle the checkbox below to understand how the fallback variable works.

Should the supplied value be an invalid value for the property, however, the fallback will not be applied.

Invalid values for properties

Indeed, any time the variable's value is invalid for the property, the value is ignored. Instead, its computed value will be the property's inherited value (if the property is inheritable), or its initial value.

In other words, --button-default: 20px would cause the background-color declaration to fail. Elements matching .button--switch would have transparent backgrounds since transparent is the initial value.

Get CSS Master

Did you learn something from this blog post? You might like my book, CSS Master. It contains several nuggets of CSS joy like this one.

Buy now from SitePoint