Hawk's By Design

CSS custom properties.

Variables. Variables are now in CSS.

Yeah, you read that right. Custom properties have been around for a little while, but are just now around the sweet spot for browser support. Because of that, I haven’t really paid them much mind until now. Of course, now the more I read about them, the more excited I get for the possibilities.

Just an FYI, I tend to flip flop between calling them custom properties and variables, just know that I’m talking about the same thing.

Basic Rundown

As I said before, a CSS custom property is basically a variable. You know, like your SASS variables, except these are actually built into CSS. The value that these variables can hold can be any property value.

So, how do you declare one of these bad boys?

:root {
    --myColor: #f00;
}
p {
    color: var(--myColor);
}

This code snippet uses the :root pseudo-class selector in order to create this custom property globally (we’ll get to scope later). Under :root, the variable name –myColor is created and given the value of #f00. This variable can be accessed anywhere in your CSS now.

The following line shows how you can read a set variable. Inside the paragraph selector, the variable is read using the var() function to set the color property. What the browser will display is paragraphs that are colored red.

Neat, right?

Before we go any further, it’s worth taking a look at the current browser support. As I said previously, it’s in a sweet spot, but there are still some sacrifices that will have to be made.

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

As you can see, Internet Explorer is out completely, and earlier versions of Edge either don’t support it or have some issues. That being said, a 91% support rating is nothing to dismiss. For comparison, and un-prefixed flexbox sits at 94%.

Ultimately, it’s a case by case call.

Scope

Whenever I first started looking into CSS variables, I was curious how scoping was going to work. Naturally, it worked pretty much like I expected.

Global

:root {
    --myColor: #f00;
}

As we went over before, in order to create a variable with a global scope, so that it can be accessed anywhere in our CSS, we declare the variable underneath the :root pseudo-class.

Selector

p {
    --myColor: #f00;
}
.some-class {
    --myColor: #0f0;
}
#some-id {
    --myColor: #00f;
}

If a variable is declared under some sort of selector, such as an element, class, or id, then the variable is limited to that selection. We could have three paragraph elements, one without a class, one with .some-class, and one with #some-id, and they’d all be different colors due to the scope of the variable.

See the Pen Basic CSS Custom Property Scope Example by Kyle Hawk (@Krazyhawk) on CodePen.

Keep in mind what scope a variable has whenever you create it. Also keep in mind that CSS specificity rules still apply, as we can see in the example as the class and id overrule the element selector.

Inline Style

<p style="--myColor: #f00"></p>

That’s right, you can assign variables their values via inline as well. I’m sure there are those out there that would advise against this, but there are always some use cases. For instance, a recent css-tricks article pointed out using inline variables to help create a staggered animation.

In case you are wondering, the application of the variable in the CSS doesn’t change. You still use the var() function and variable name like before.

JavaScript

I bet you didn’t think we’d be talking about JavaScript, did you? Well, one of the many cool features of custom properties is their ability to be able to be updated via JavaScript.

I don’t think I need to explain how monumental this one little feature is. In just a couple lines of JavaScript you can update a variable name, which will then update anywhere it is referenced. The possibilities are astounding.

Let’s see how this looks.

// Get styles for element
var styles = getComputedStyle(document.documentElement);
// Get custom property value
var myColorValue = styles.getPropertyValue('--myColor');

// Set the custom property value
document.documentElement.setProperty('--myColor', '#0f0');

The snippet above helps us update a variable called –myColor that has been assigned to the :root pseudo-class. If you want to get or set a variable on a different element, then you adjust the element you are selecting accordingly.

The first block of this code first gets the computed style for the documentElement, this is how we access variables that are under :root. Then, we use the getPropertyValue() function and pass it the name of the variable. What’s returned is the value of the variable.

Setting a property value is even easier, and can be done in a single line. First you grab the element you want to update, then under style you invoke the setProperty function. The first argument is the custom property name, and the second is the value you want the property to have. If the second is left blank, it’s treated as an empty string.

The following is an example if you have a property on a class that you are wanting to update.

// Get the class
var someClass = document.querySelector('.some-class');

// Read the custom property value
var styles = getComputedStyle(someClass);
var myColorValue = styles.getPropertyValue('--myColor');

// Set the custom property value
someClass.setProperty('--myColor', '#0f0');

Exciting Future

CSS has been making some crazy leaps lately, it’ll be interesting to see just how far it goes in the future. When I was in school, separation of concerns was a huge deal between HTML / CSS / JavaScript; the culprit mostly being JavaScript. As CSS progresses rapidly, I wonder if there is going to be concern there.

I’m personally on the fence as to whether or not I want to start using custom properties in my projects. I would love to, but using them would be removing support for IE11…which, depending on the project, can be a big deal.

Oh well. One thing that can’t be denied is just how fun they are to work with!

Thanks for reading.

Some more articles for you

Coding

May 29, 2019

Intersection Observer: A Great New API

Finding out if an element is within the viewport has always been a pain in the butt. Luckily, there's a handy new API called Intersection Observer.

View post

Coding

August 27, 2019

Iframe Lazy Loading – Srcdoc to the rescue?

Iframes can be an expensive resource, especially for videos. Lazy loading iframes isn't as easy as it should be, but maybe the srcdoc attirbute can help.

View post