DEV Community

Habdul Hazeez
Habdul Hazeez

Posted on • Updated on

CSS Variables

In computer science and programming, variables are memory locations that store data, and the data can be accessed later via the variable name. Some programming language allow the reassignment of the same variable name to another data or value in the program and the compiler or interpreter will just do the same during the course of the program execution and some programming language strictly forbid this.

Forgive me if the last paragraph seems intimidating to you if you've not programmed before and if you follow this series till the end, you will definitely write a few programs (in the JavaScript section) to perform basic tasks albeit in the web browser.

I know this post is about CSS variables and some will argue that CSS developers are not really programmers, but we just need to know the uses of variables and where they originated from which is why this post started the way it did.

Variables have been a requested feature in CSS since the year 1998. Dave Hyatt and Daniel Glazman shaped the first concrete proposal in 2008.

Some were concerned that CSS needed no variables and Bert Bos considered CSS variables harmful.

Fast forward to 2012, the specification was provided by the World Wide Web Consortium (W3C) and CSS variables were implemented in Chrome and Firefox. Two years later, the specification was improved, Firefox modified their implementation and Chrome postponed their implementations effort to allow things to settle down.

In the late 2015, browser support was minimal for CSS variables, however in 2016 the browser support went up.

The question now is: Why variables in CSS? When you work on a project (big or small) you'll use CSS for the layouts, backgrounds, colors e.t.c and some property declarations will be duplicated across multiple CSS rules. For example:

p {
  color: #1560bd;  /* duplicate */  
  font-size: 1.2em;
}

span {
  color: #1560bd;  /* duplicate */
  display: block;
}
Enter fullscreen mode Exit fullscreen mode

Now, let's see how we can use variables in our CSS code.

I'll be making use of the specification in subsequent explanations, so I'll encourage you to open the link in a new tab or a new window in your web browser.

Save the following HTML with the .html extension and create a blank CSS file and make sure its linked with the HTML file. All HTML snippet will be in the body tag.

<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo
consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur.
<span>Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt</span>
mollit anim id est laborum.</p>
</div>
Enter fullscreen mode Exit fullscreen mode

And kindly note that all screenshots are from Firefox 70 web browser and its Developer Tools.

With that out of the way. Let's start.


Officially speaking, CSS variables are called custom properties in the specification. The specification defines a custom property as:

any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo

I believe this explanation is straight forward but lets clarify it with code.

Using our previous example, we can declare the color at a single place and we will be able to reuse it in the p and span elements.

:root {
  /*
   * the --color is the variable here and 
   * #1560bd is the value.
  */

  --color: #1560bd;
}
Enter fullscreen mode Exit fullscreen mode

In the code snippet above, the variable is declared in the :root pseudo-class which represents the root element (html) and hence it will be available to all page element since all page elements are descendants of the root element.

Now that we have declared our variable, You might ask: How can we access the variable? We can access our declared variable using the var() function.

The job of the var() function is to substitute the value of the variable into another property.

The function accepts two arguments (values):

  • The first argument to the function is the name of the custom property (the variable) to be substituted.
  • The second argument to the function, if provided, is a fallback value, which is used as the substitution value when the referenced custom property is invalid.

Its syntax is as follows:

var( variable name, fallback value(s) )

Using our previous CSS example, the

  • variable name will be --color
  • The fallback value(s) is used when the variable value is invalid

We'll demonstrate the fallback value later, but for now let's update our code to use variables. Let your CSS match the following:

:root {
  /*
   * the --color is the variable here and 
   * #1560bd is the value.
  */

  --color: #1560bd;
}

p {
  color: var(--color);  /* variables!! */
  font-size: 1.2em;
}

span {
  color: var(--color); /* variables!! */
  display: block;
  font-weight: bold;
}
Enter fullscreen mode Exit fullscreen mode

Save and refresh your file. The p and span text element will be a variant blue.

A blue text on a white background

VARIABLES AND INHERITANCE

Custom variables are inherited, which means a child element can use the value of a variable in its parent's element.

Using the previous CSS code. Perform the following actions:

  • Load the HTML in your browser
  • Use "Inspect Element" on the text
  • Check under the Rules tab

A web browser with Developer tools opened

You will notice that the color of the p element is actually inherited from the :root element.

This tells us that: CSS variables (custom properties) can be inherited and like most properties that can be inherited from the parent element we can reassign the value in the child element.

Update your p element CSS rule to match the following:

p {
  --color: blue;       /* Note this */
  color: var(--color);
  font-size: 1.2em;
}
Enter fullscreen mode Exit fullscreen mode

Save your file, refresh your browser and note the change in the Developer Tools. You will realize the p element is now using the value of the variable we declared in its CSS rule and not the inherited value from the :root element. The span is also blue because it's a child element of p.

A blue text on a white background

INVALID VARIABLES

From the specification (emphasis mine):

A variable can be invalid if it uses a valid custom property, but the property value, after substituting its var() functions, is invalid.

When this happens, the computed value of the property is either the property’s inherited value or its initial valuewhether the property is inherited or not, respectively, as if the property’s value had been specified as the unset keyword.

This means: when we declare a property in our CSS rule and then we decide to assign it a value using a variable, if the variable contains a value that is invalid to this said property, the browser will use the property initial value* unless we explicitly specify a fallback value. Say what?

*The initial value is the elements default value.

Given the code snippet below.

body {
  --color: 23;                    /* Note this */
}

div {
  background-color: var(--color); /* This wont work */
}
Enter fullscreen mode Exit fullscreen mode

Save and refresh your browser. You'll notice the background color is white. Why? What happened?

We declared a variable with the following:

body { --color: 23; }

This is fine and the variable is valid, then we used it for the background-color in our div element.

div { background-color: var(--color); }

This is the same as writing:

div {background-color: 23; }

The last time i checked 23 is not a valid background color, so the browser used the background-color initial value which is white (#ffffff in Hex and rgba(0,0,0,0,0) in rgb format). You can see this in the Computed tab of the Developer Tools.

A black text on a black background

This means we should note our variable values and make sure they will work when we need them.

A variable can also be invalid if its value is invalid. The spec states:

While <declaration-value> must represent at least one token, that one token may be whitespace.

This means: if the value of your variable is empty it will be invalid and this is when the fallback value comes into the picture.

Update your CSS to match the following:

body {
  --color:;                               /* The value is empty */
}

div {
  background-color: var(--color, green);  /* The fallback value will be used */
  padding: 1.2em;
  color: #ffffff;
}
Enter fullscreen mode Exit fullscreen mode

It's evident from the code above that our --color variable has an empty value. Save your file and refresh your browser. The browser will apply the green fallback color.

a white text on a green background

Somethings to note about CSS variables or custom properties:

  • Their names are case-sensitive. Which means --color is not the same as --Color
  • You cannot reset a CSS variable with the all property
  • The CSS-wide keywords can be used in CSS variables

BROWSER SUPPORT

Based on data available at caniuse, the global usage of CSS variables as of November 2019 is 93.16%with decent browser support.

Caniuse data on CSS variables

THINGS I LEFT OUT

I consider this topics "advanced" for this beginners post.

  • Dependency Cycles
  • Global and Local Scope

You might be feeling adventurous, so here are some links for you:

We are getting closer to CSS properties that will aid us in web page layouts.

We'll start with CSS Floats. Next.

Updated July 1, 2021: Changed a statement in paragraph 4 under "VARIABLES AND INHERITANCE" to reflect that you can only reassign a variable in child elements and not change them.

Top comments (0)