CSS Variables
Tags: beginners, css
Published: 2019-11-14 21:50:04

---
title: CSS Variables
published: true
description: A beginners guide to CSS variables
tags: beginners, css
series: FrontEnd Development Zero to Hero
---
_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]( http://disruptive-innovations.com/zoo/cssvariables/) in 2008.

Some were concerned that [CSS needed no variables]( https://meiert.com/en/blog/why-css-needs-no-variables/) and Bert Bos [considered CSS variables harmful]( https://www.w3.org/People/Bos/CSS-variables).

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:

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

span {
  color: #1560bd;  /* duplicate */
  display: block;
}
```

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

I'll be making use of the [specification]( https://www.w3.org/TR/css-variables-1/) 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._

```html
<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>
```

_And kindly note that all screenshots are from <b>Firefox 70</b> web browser and its Developer Tools._

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

<hr>

Officially speaking, CSS variables are called _custom properties_ in the [specification]( https://www.w3.org/TR/css-variables-1/#defining-variables). The [specification defines a custom property]( https://www.w3.org/TR/css-variables-1/#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.

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

  --color: #1560bd;
}
```

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:

```css
: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;
}
```

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

![A blue text on a white background](https://thepracticaldev.s3.amazonaws.com/i/o6hypll5511w81mbkdjc.PNG)

###__VARIABLES AND INHERITANCE__
Custom variables are [inherited](https://dev.to/ziizium/css-inheritance-3pi1), 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](https://thepracticaldev.s3.amazonaws.com/i/qmk06kz9wmquzba9pox0.PNG)

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:

```css
p {
  --color: blue;       /* Note this */
  color: var(--color);
  font-size: 1.2em;
}
```

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](https://thepracticaldev.s3.amazonaws.com/i/t3f3ybk7qnwoee1w76ik.PNG)

###__INVALID VARIABLES__
From the [specification] (https://www.w3.org/TR/css-variables-1/#invalid-at-computed-value-time) (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 <b>computed value of the property is either the property’s inherited value</b> or its <b>initial value</b depending on <b>whether the property is inherited or not</b>, 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?

<center><small>_*The initial value is the elements default value._</small></center>

Given the code snippet below.

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

div {
  background-color: var(--color); /* This wont work */
}
```

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](https://thepracticaldev.s3.amazonaws.com/i/afphedee0vn8688b88vw.PNG)

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]( https://www.w3.org/TR/css-variables-1/#syntax) 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:

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

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

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](https://thepracticaldev.s3.amazonaws.com/i/gfpub4y1i4of8s9jk3t0.PNG)

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](https://www.w3.org/TR/css3-values/#common-keywords) can be used in CSS variables

###__BROWSER SUPPORT__
Based on data available at [caniuse](https://caniuse.com/#feat=css-variables), the global usage of CSS variables as of November 2019 is `93.16%`with decent browser support.

![Caniuse data on CSS variables](https://thepracticaldev.s3.amazonaws.com/i/8nr97ysv0zu33ujhsooi.png)


###__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:
* [Scope in CSS](https://www.quirksmode.org/blog/archives/2019/03/scope_in_css.html)
* [Resolving Dependency Cycles](https://www.w3.org/TR/css-variables-1/#cycles)

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_.