Skip to content

24 ways to impress your friends

Getting Hardboiled with CSS Custom Properties

Custom Properties are a fabulous new feature of CSS and have widespread support in contemporary browsers. But how do we handle browsers without support for CSS Custom Properties? Do we wait until those browsers are lying dead in a ditch before we use them? Do we tool up and prop up our CSS using a post-processor? Or do we get tough? Do we get hardboiled?

Previously only pre-processing tools like LESS and Sass enabled developers to use variables in their stylesheets, but now Custom Properties have brought variables natively to CSS.

How do you write a custom property? It’s hardly a mystery. Simply add two dashes to the start of a style rule. Like this:

--color-text-default : black;

If you’re more the underscore type, try this:

--color_text_default : black;

Hyphens or underscores are allowed in property names, but don’t be a chump and try to use spaces.

Custom property names are also case-sensitive, so --color-text-default and --Color_Text_Default are two distinct properties.

To use a custom property in your style rules, var() tells a browser to retrieve the value of a property. In the next example, the browser retrieves the black colour from the color-text-default variable and applies it to the body element:

body {
    color : var(--color-text-default); 
}

Like variables in LESS or Sass, CSS Custom Properties mean you don’t have to be a dumb mug and repeat colour, font, or size values multiple times in your stylesheets. Unlike a preprocessor variable though, CSS Custom Properties use the cascade, can be modified by media queries and other state changes, and can also be manipulated by Javascript.

(Serg Hospodarets wrote a fabulous primer on CSS Custom Properties where he dives deeper into the code and possible applications.)

Browser support

Now it’s about this time that people normally mention browser support. So what about support for CSS Custom Properties? Current versions of Chrome, Edge, Firefox, Opera, and Safari are all good. Internet Explorer 11 and before? Opera Mini? Nasty.

Sound familiar?

Can I Use css-variables? Data on support for the css-variables feature across the major browsers from caniuse.com.

Not to worry, we can manually check for Custom Property support in a browser by using an @support directive, like this:

--color-text-default : black;

body {
    color : black;  
}

@supports ((--foo : bar)) {
    body {
        color : var(--color-text-default); 
    }
}

In that example we first set body element text to black and then override that colour with a Custom Property value when the browser supports our fictitious foo bar variable.

Substitutions

If we reference a variable that hasn’t been defined, that won’t be a problem as browsers are smart enough to ignore the value altogether. If we need a cast iron alibi, use substitutions to specify a fall-back value.

body {
    color : var(--color-text-default, black); 
}

Substitutions are similar to font stacks in that they contain a comma separated list of values. If there’s no value associated with a property, a browser will ignore it and move onto the next value in the list.

Post-processing

Of course we could use a post-processor plugin to turn Custom Properties into plain CSS, but hang on one goddam minute kiddo.

Haven’t we been down this road before? Didn’t we engineer elaborate workarounds to enable us to use ‘advanced’ CSS3 properties like border-radius, CSS columns, and Flexbox in the past? We did what we had to do to get the job done, but came away feeling dirty.

I think there’s a better way, one that allows us to enjoy the benefits of CSS Custom Properties in browsers that support them, while providing an appropriate, but not identical experience, for people who use less capable browsers. Guess what, I’ve been down this road before too.

2Tone Stuff & Nonsense

When Internet Explorer 6 was the big dumb browser everyone hated, I served two different designs on my website.

For the modern browsers of the time, mod arrows and targets were everywhere in glorious red, white, and blue, and I implemented all of them using CSS attribute selectors which were considered advanced at the time:

[class="banner"] {
    background-colour : red; 
}

Internet Explorer 6 ignored any selectors it didn’t understand, so people using that browser saw a simpler black and white, 2Tone-based design that I’d implemented for them using class selectors:

.banner {
    background-colour : black; 
}

[class="banner"] {
    background-colour : red; 
}
Screen shot of the Stuff & Nonsense website side by side in different browsers, showing the differences in rendering between the two browsers.

You don’t have to be a detective to find out that most people thought I’d lost my wits, but Microsoft even used my website as a reference when they tested attribute selectors in Internet Explorer 7. They did, as I suggested, “Stomp to da betta browser.”

Dumb browsers look the other way

So how does this approach relate to tackling any lack of support for CSS Custom Properties? How can we take advantage of them without worrying about browsers with no support and having to implement complex workarounds, or spending hours specifying fallbacks that perfectly match our designs?

Turns out, the answer is built into CSS, and always has been, because when browsers don’t know what they’re looking at, they look away.

All we have to do is first specify values for a simpler design first, and then follow that up with the values in our CSS Custom Properties:

body {
    color : black;
    color : var(--color-text-default, black); 
}

All browsers understand the first value (black,) and if they‘re smart enough to understand the second (var(--color-text-default)), they’ll use it and override the first. If they’re too damn stupid to understand the custom property value, they’ll ignore it. Nobody dies.

Repeat this for every style that contains a variable, baking an alternative, perhaps simpler design into your stylesheets for people who use less capable browsers, just like I did with Stuff & Nonsense.

Conclusion

I doubt that anyone agrees with presenting a design that looks broken or unloved—and I’m not advocating for that—but websites need not look the same in every browser. We can use substitutions to present a simpler design to people using less capable browsers.

The decision when to start using new CSS properties isn‘t always a technical one. Sometimes a change in attitude about browser support is all that’s required. So get tough with dumb browsers and benefit from all the advantages that CSS Custom Properties offer. Get hardboiled.

Resources:

About the author

Andy Clarke is one of the world’s best-known digital designers, a speaker, and writer, now based in Sydney, Australia. He works as Head of Design at Ansarada, helping the company to express its brand strategy through digital products and marketing. Andy founded Stuff & Nonsense in 1998 specialising in creative design for digital products and websites.

Andy’s the author of three web design books including ‘Transcending CSS’ and ‘Hardboiled Web Design Fifth Anniversary Edition’ and is known for his many conference presentations and contributions to the web design industry. He really, really loves gorillas.

More articles by Andy

Comments