CommonLounge Archive

CSS Variables

March 21, 2019

Motivation

Variables are a common feature of most programming languages. To give an example of why variables in CSS can be useful, consider the following scenario:


When programming the UI for an application, you have picked a set of colors suitable to the constraints relating to the UI design of your web app. Following best practices, you then compose a few of your chosen colors into a theme, to provide a consistent look for your application.

In this scenario, you may need to change a certain color used across your application. This is not easy, if your application is large with its CSS source files running more than, say, 20,000 lines of code. To complete this task without variables, you would need to run several find and replace operations on your code editor, an uphill task prone to error.

You realize that using variables could simplify things for you…

You could define your color with a meaningful name in one place, and refer to it in several other places. This would reduce repetition, and improve readability in your CSS code base. To replace your color with a new value, you need to change the definition of color once. Now, every place where the color is referenced in your application would get updated to the new value simultaneously!

How would you start including them in your CSS, you wonder…


In this tutorial, we will learn important concepts related to CSS variables. Let’s dive in!

Introduction

Until the recent past, variables were not supported in the CSS language. You would need to be familiar with advanced external utilities such as CSS preprocessors to use them.

Today, CSS Variables, also known as custom properties, are a native feature of the language implemented by most web browsers. They are useful for reducing repetition by the reuse of CSS code. That’s a big win! Complex websites today, in many occasions, have lots of CSS with repeated values!

The second benefit of CSS variables is meaningful variable identifiers. For example, the variable name, --site-theme-color is a lot simpler to understand than say, #4a90e2(a shade of blue). This is particularly true in case this same color (#4a90e2) is used in various other contexts in a given application.

Syntax and basic usage

CSS variables are properties that begin with a double dash. For example, --site-theme-color is a valid CSS variable name.

Scoping rules

Variables can be declared in global or local scope.

Declaring variables in the global scope

You can create globally scoped variables, which can be referenced by any CSS ruleset in the CSS document. They are declared under the :root pseudo class, like so:

:root {
  --property-name: value
}

The :root pseudo class maps to the root element of the DOM tree (typically the <html> element).

Declaring variables in the local scope

You can create variables declared in local scope, which can be accessed by the element where the variable is declared and by its children.

For example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <style>
      .container {
        --color: #447589;
       }
      /* 'color' variable is defined under the container class scope*/
      .container p {
         border: 2px solid var(--color);
       }
      /* All p tags that are children of elements with the container class have access to the 'color' variable */
    </style>
  </head>
  <body>
    <div class="container">
      <p>This paragraph's border color is a shade of blue.</p>
    </div>
  </body>
</html>

Click on Try it Now above and hit the Run button to see the result for yourself!

Time for a quiz question!

Variable access

Variables can be accessed in two ways:

With the var() function

Variables are typically accessed with the var() function. Thevar()function is replaced with the value of the CSS variable.

Let us illustrate this with an example.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <style>
      :root {
        --site-theme-color: #9DD8E6;
      }
      .header {
        background-color: gray;
        padding: 20px;
        margin: 20px;
        height: 20%;
      }
      .body {
        color: white;
        background-color: var(--site-theme-color);
        padding: 20px;
        margin: 20px;
        height: 70%;
      }
      .footer {
        color: white;
        background-color: var(--site-theme-color);
        padding: 20px;
        margin: 20px;
      }
    </style>
  </head>
  <body>
    <div class="header">HEADER</div>
    <div class="body">BODY</div>
    <div class="footer">FOOTER</div>
  </body>
</html>

In the above example, background-color statements make use of the CSS variable,--site-theme-color. The var() functions present in these statements are replaced with the value of --site-theme-color, #447589.

With the calc() function

In most programming languages, we can assign an arithmetic expression to a variable. We can do this in CSS with the calc() function. Let us illustrate this with an example.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <style>
      :root {
        --height: 500px;
      }
      .containerA {
        border: 2px solid black;
        height: var(--height); /*replaced with value of height variable: 500px */
      }
      .containerB {
        border: 2px solid black;
        height: calc(var(--height) * 2 ); /* 1000px */
      }
    </style>
  </head>
  <body>
    <div class="containerA">Container A | Height: 500px</div>
    <div class="containerB">Container B | Height: Height(Container A) * 2px = 1000 px</div>
  </body>
</html>

In the above example, containerB class’s height property is computed using the calc() function.

Cascade and Inheritance rules

Variables in CSS are subject to standard cascade and inheritance rules.

Let us illustrate this with an example.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <style>
      :root { 
        --color: blue; 
      }
      div {
        --color: gray; 
      }
      #container { --color: gold; }
      * { color: var(--color); }
    </style>
  </head>
  <body>
    <span>This span of text has blue text color from the * selector.</span>
    <div>This div has a gray text color from the div selector which cascades over the * selector.</div>
    <div id="container">
      This div has a gold text color from the #container selector (cascading over the div selector) .
      <p>This paragraph has gold text colour via inheritance.</p>
    </div>
  </body>
</html>

In the above example, the same variable, --color, is declared at different levels of specificity. As there is no value set for text color for the p element, CSS inheritance rules are applied which means that the text color of the p element is set to the value of its parent div element.

Note: The value of a CSS variable is computed during its access time, it is not stored in memory for later use by other rules.

Invalid CSS variables

If a CSS statement (a property, value pair) without variables, is invalid, i.e has a syntax error, that statement is ignored and the property is set to its cascaded value.

For example,

p { 
  color: blue;
}
p { 
  color: 16px; /* this statement is a syntax error, color is set to blue, using standard cascading rules. */
} 

In case a CSS statement with variables is invalid, the property is set to its inherited value, if applicable. Else, the property value is set to its default initial value.

Consider the following example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <style>
    :root { 
      --color: 16px; 
     } 
    p { 
      color: gray; 
    } 
    p { 
      color: var(--color); 
    }
    </style>
  </head>
  <body>
    <p>This paragraph has black text color.</p>
  </body>
</html>

In the above code, consider the statement color: var(--color) present within the second p CSS rule:

  1. The browser replaces the variable --color with its value (16px).
  2. As 16px does not make sense as a color property value, the statement is invalid.
  3. The brower checks if color property can be inherited from the p element’s parent’s rules.
  4. As the p element does not have a parent with color property, the property will default to its initial value, black.

Fallback values

In a CSS statement (a property, value pair) with variables, if the variable name present in the statement is not yet defined, we can allow it to fall back to a default value with the help of the var() function.

The var() function supports a maximum of 2 arguments. The first argument is required to be present and denotes the name of the CSS variable to be replaced with a value. The second argument is optional, which if provided, becomes a fallback value if the first argument (the variable name) is not defined.

It has the syntax, var(<variable_name> [, <fallback_value> ]? )

Note: The ? in the above expression indicates that the second argument may or may not be present.

Let us illustrate this with an example.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <style>
      p {
        color: var(--color, blue); 
      }
    </style>
  </head>
  <body>
    <p>This paragraph has blue text color.</p>
  </body>
</html>

In the above example, the color property is assigned the value blue since the--color variable is not defined.

CSS variables in JavaScript

We can use CSS variables in JavaScript. Suppose we have a reference to a DOM element, element:

var element = <element in DOM tree>

Get property value

We can get the value of a CSS variable, --variable, by using the DOM element’s style object’s getPropertyValue() method, like so:

// Get variable value from an element’s set of css properties defined within the element’s inline style. 
element.style.getPropertyValue("--variable");
// Get variable value from an element’s complete set of CSS properties.
getComputedStyle(element).getPropertyValue("--variable");

Set property value

We can set the value of a CSS variable --variable, by using the DOM element’s style object’s setProperty() method, like so:

// Set a CSS variable property on an element’s inline style.
element.style.setProperty("--variable", 2000);

Let us illustrate this with an example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <style>
    p { 
      color: var(--color); 
    }
    </style>
  </head>
  <body>
    <p id="text">This paragraph has gold text color.</p>
    <script>
      var element = document.getElementById("text");
      // Set CSS variable property on an element’s inline style.
      element.style.setProperty("--color", "gold");
    </script>
  </body>
</html>

Conclusion

In this tutorial, we covered the important concepts of CSS Variables including

  • syntax,
  • var()/calc() functions,
  • fallback values,
  • cascade/inheritance rules, and their
  • basic usage in JavaScript and CSS.

More Examples


© 2016-2022. All rights reserved.