In this post, we will talk about CSS custom properties, also known as CSS variables. Their usage is becoming more popular. For example, if you open up the style sheet of the Twenty Twenty-One default theme, you will find a lot of them in there.

twenty twenty one style sheet css variables

One of the reasons is that their browser support has become very good, making them a valid tool in your arsenal and a useful CSS feature.

css variables custom properties browser support

If your knowledge of CSS custom properties is limited and you’d like to know more, you have come to the right place. In the following, we will talk about what exactly they are, pros and cons, how to use them, and some examples and use cases.

What Are CSS Custom Properties?

Before getting to the how-to part, let’s have a conversation about what custom properties are in the first place. As mentioned above, another name under which they are known is CSS variables. Knowing that already brings us closer to their function.

In web development, mathematics, and other disciplines, variables are stand-ins for other values. You might recall being asked to solve for x in middle school, and ending up with a result like x=2.

CSS variables are the same. They are markers that stand for or contain other values. Here’s what that looks like:

color: var(--global--color-primary);

As you can see in the example above, instead of color being declared as a proper value, here, instead it says var(--global--color-primary) .

Why would you do it this way instead of simply writing out an HTML color code? Let’s talk about that now.

CSS Variables: The Benefits

CSS markup is by default very repetitive. For example, if you have settled on a color scheme for your website, you will use declarations for the same five colors or so in the entire design – again and again.

.navigation { 	color: #28303d; }  .footer-navigation { 	color: #28303d; }  .entry-footer { 	color: #28303d; }

This also means that, if you want to change your color scheme or even just one hue, you have to find and replace every single instance of it. Sure, code editors make this really easy but CSS variables offer an even better way.

What if, instead of declaring the same color every single time, you could use a placeholder and define its property only once, in one central place?

Sounds great? Because that is exactly how CSS custom properties work.

body { 	--global--color-primary: #28303d; }  .navigation { 	color: var(--global--color-primary); }  .footer-navigation { 	color: var(--global--color-primary); }  .entry-footer { 	color: var(--global--color-primary); }

As you can imagine this can save web developers and designers a lot of time and effort, which is one of the main benefits CSS custom properties.

Aside from that, they are easier to identify and understand. --global--color-primary is clearer than a random color value like #28303d and can make comprehending markup, especially such that you haven’t written yourself, much easier.

Also, the use of CSS custom properties reduces repetition (see DRY codingdon’t repeat yourself), possibly meaning savings in computing time, disk space, and page loading time.

You could even use them to offer more than one color scheme, such as dark mode, as is already available on click in Twenty Twenty-One.

twenty twenty one dark mode activated on front end

Custom properties are also very flexible and have a lot of other practical use cases as we will see below.

In addition, they work well with JavaScript. You can target them easily with the .getPropertyValue() and .setProperty() methods and manipulate them in many different ways.

Finally, as already mentioned in the introduction, browser support is excellent.

Disadvantages of Custom Properties

So, are there any downsides to using these CSS properties? Sure thing, nothing is without the other side of the coin.

In this case, it can be the added complexity. If you use a lot of variables, you need to keep track of their names and which one does what.

In addition, CSS custom properties are not compatible with older browsers and it’s not always easy to declare fallbacks (we will cover this below).

Finally, depending on their usage, CSS custom properties can have an impact on page performance. Since page speed is a very important quality marker for websites, this is something you should be aware of.

However, overall, the pros of this technology outweigh the cons pretty heavily. Let’s see how you can take advantage of it, shall we?

How to Use CSS Variables – Step-by-Step

In order to use custom properties, the first thing you need to do is define them. They may take on any valid CSS value: color, size, string, time, you name it.

--main-color: #1f8aad; --default-box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6); --letter-spacing: normal; --font-primary: -apple-system, BlinkMacSystemFont, Roboto, sans-serif; --logo--max-width: 300px;

Secondly, they have to be within a selector, which also defines their scope. A common practice is to define properties that you want to use globally, such as for a color scheme, at the beginning of your style sheet under the :root selector.

:root { 	--global--color-black: #000; 	--global--color-dark-gray: #28303d; 	--global--color-gray: #39414d; 	--global--color-light-gray: #f0f0f0; }

In case you are wondering, :root is the same as html but more specific.

As you have probably already picked up on from the examples above, the way to declare a variable in CSS is to put -- in front of it. Once defined, you can then use variables wherever you need them via var() with the name of the custom property inside.

.entry-content { 	color: var(--global--color-dark-gray); }

Pretty straightforward though, right? A few more things to keep in mind:

  • Custom property names can contain letters, numbers, dashes
  • They are case sensitive, so --maincolor and --MainColor are going to be treated as different variables
  • The properties inherit, so if you define a custom property for a parent element but not its child, the latter will inherit the parent’s value when a custom property is used

And that’s it, this is how to use CSS variables on the most basic level. Of course, the devil is in the details, so let’s go over some use cases and practical examples to explore the topic some more.

Use Cases and Examples

In order to better understand CSS custom properties, we will finish this post with some practical examples so you get an impression of their application.

Place Variables Inside Variables

A cool thing about CSS variables is that you can nest them inside one another. Let’s say you want to set up a global main color and use that same color for your borders. You can do that like so:

:root { 	--global--color-border: var(--global--color-primary);  }

Why would do this? It comes down to the naming conventions of variables. When defining the border color further down, you might not be sure if it was the global primary color or something else. However, you don’t have to know. You can simply use the global border color and the rest is already taken care of.

Change a Value Depending on Context

As mentioned earlier, the CSS selector under which you define a custom property also defines its scope. That also means that you can change the value of a property depending on context.

:root { 	--main-color: #1f8aad; }  .landing-page-header { 	--main-color: #183cba; 	color: var(--main-color); }

In the example above, we have defined --main-color under the :root selector to define it globally. However, in the context of .landing-page-header we want it to have a different value. For that reason, we re-define --main-color under the new selector before using it. This creates an exception for this one context without touching the initial value.

Declare a Fallback for Older Browsers

Though browser support is good, older browsers struggle with CSS custom properties. For that reason, it’s sometimes necessary to input a fallback.

However, this doesn’t work as easily as, for example, a font family where you can just give several options and the browser can work its way down the line. Instead, in many cases, you have to first declare the fallback and then follow it up with the custom property.

:root { 	--main-color: red; }  .entry-header { 	background-color: red; /* fallback */ 	background-color: var(--main-color); }

That way, newer browsers will pick up the second declaration (because it overwrites the first) but older browsers that don’t know CSS variables will just ignore the second line as invalid.

Define Fallbacks for Missing Values

Another case in which we might need a fallback is when a custom property value has not been defined. Stuff like that happens sometimes and important things get overlooked.

No worries, CSS variables also allow for that case and it looks like this:

.widget-title { 	font-family: var(--heading-font, Roboto); }

In case custom property --heading-font is not defined, the browser can simply go down the line and use the fallback Roboto.

It’s actually quite straightforward. The only thing you have to keep in mind is that the fallback also needs to be inside the brackets of var().

You can also use a variable as a fallback of another variable AND include an additional fallback value.

.widget-title { 	font-family: var(--heading-font, var(--base-font, Roboto)); }

Do Operations Using CSS Variables

In addition to the above, you are also able to use CSS custom properties inside operations. You can add, subtract, multiply, and divide them to your heart’s content with calc().

You can use this, for example, to define a ratio of font sizes that stays the same even if the initial font size changes.

:root {	 	--font-size-base: 1.25rem; 	--heading--font-size-h1: calc(2.5 * var(--font-size-base:)); 	--heading--font-size-h2: calc(2 * var(--font-size-base:)); 	--heading--font-size-h3: calc(1.75 * var(--font-size-base:)); }

Other popular examples for this are to calculate spacing or complementary colors.

Split Up Values for More Control

Another cool application for CSS custom properties is that they allow you to split up CSS values in order to control different parts of them. For example, instead of repeating a rgba() declaration, you can split it up into variables and only change the ones you need.

:root { 	--r: 255; 	--g: 0; 	--b: 0; 	--a: 0.8; }  .widget { 	--r: 0; 	--g: 255; 	background-color: rgba(var(--r), var(--g), var(--b), var(--a)); }

You can also use this to change a property after a media query so that it looks different in responsive design.

@media only screen and (min-width: 482px) { 	 	:root { 		--r: 0; 		--g: 255; 	} 	 }

Improve Your Development Workflow With CSS Custom Properties

CSS variables or custom properties are a great tool to have in the design/development toolbox. They allow you to cut down on repetition, make global changes more simple, and add automatic documentation to your style sheets. Plus, as you have hopefully seen above, they are pretty easy to use and quite self-explanatory.

With the information in this post you are now ready to give CSS custom properties a try yourself and dive deeper into the topic. There is a lot more to discover, so this is just the beginning.

What’s your favorite use case for CSS variables? Let us know in the comments below!