CSS Variables Tutorial – var() and Custom Properties Explained
CSS variables are the custom CSS properties developers define for easy reuse throughout a stylesheet.
How to Create CSS Custom Properties
A CSS variable is a name/value pair. So, to create one, set a custom name of your choice to a value you wish to reuse.
Here’s the syntax:
--your-custom-name: value;
Note the following:
- A custom property’s name must begin with two hyphens (
--
). - A CSS variable’s name is case sensitive. Therefore,
--primary
is different from--Primary
. - Cascading variables accept valid CSS values only.
Here’s an example:
body { --primary-text-color: #0000ff;}
The CSS snippet above defined a --primary-text-color
for the <body>
element. Therefore, you can reuse the custom property’s value (#0000FF
) on any of the <body>
’s content.
CSS Variable’s Scope
CSS selectors define custom properties’ scope. In other words, you can only use a cascading variable for the selected HTML element.
Let’s see some examples.
Example of a locally scoped CSS variable
Consider the following CSS snippet:
section { --main-highlight-color: #ccff00;}
In the snippet above, --main-highlight-color
is locally scoped to the document’s <section>
elements. Therefore, we can use it for <section>
nodes only.
Example of a globally scoped CSS variable
Developers often define global custom properties on the :root
pseudo-class selector to make the variables available globally to all the document’s elements.
For instance, we can use the custom property below on any element because we defined it on the root element.
:root { --button-hover-shade: #8b008b;}
Note the following:
- A
:root
pseudo-class selector selects a document’s root element. - The
<html>
node is an HTML document’s root element. - A
:root
pseudo-class has higher CSS specificity than thehtml
name selector.
How to Access a Custom Property’s Value
The var()
CSS function allows you to access your predefined custom properties. Here is how:
- Set the
var()
CSS function as your style declaration’s value. - Provide your custom property as the
var()
function’s argument.
Here’s an example:
/* Define your custom variables on the root element */:root { --my-custom-property: #ff1493;}
/* Access your custom variables */p { color: var(--my-custom-property);}
<article> <h1>Article's first heading 1 element</h1> <p>Article's first paragraph element</p> <h2>Article's first heading 2 element</h2> <p>Article's second paragraph element</p> <p>Article's third paragraph element</p></article>
Syntax of the var()
CSS Function
The var()
CSS function accepts two arguments. Here is the syntax:
property-name: var(--custom-property, fallback-value);
--custom-property
is the CSS variable you wish to use for your style declaration.- The
fallback-value
is optional. Browsers will use it if--custom-property
is invalid or undefined.
Examples
Below are examples of how to use the var()
CSS function.
Define var()
with no fallback argument
/* Define your custom variables on the root element */:root { --primary-heading-color: #ff1493;}
/* Use --primary-heading-color as the heading's text color */h1 { color: var(--primary-heading-color);}
<article> <h1>Article's first heading 1 element</h1> <p>Article's first paragraph element</p> <h2>Article's first heading 2 element</h2> <p>Article's second paragraph element</p> <p>Article's third paragraph element</p></article>
Define var()
with a regular fallback argument
/* Define your custom variables on the root element */:root { --primary-heading-color: #ff1493;}
/* Use --primary-heading-color as the heading's text color */h1 { color: var(--primary-heading-color);}
/* Use #006400 as the paragraph's text color if --main-text-color is undefined */p { color: var(--main-text-color, #006400);}
<article> <h1>Article's first heading 1 element</h1> <p>Article's first paragraph element</p> <h2>Article's first heading 2 element</h2> <p>Article's second paragraph element</p> <p>Article's third paragraph element</p></article>
Define var()
with a var()
fallback argument
/* Define your custom variables on the root element */:root { --primary-heading-color: #ff1493; --alternative-text-color: #e25822;}
/* Use --primary-heading-color as the heading's text color */h1 { color: var(--primary-heading-color);}
/* Use #006400 as the paragraph's text color if --main-text-color and --alternative-text-color are undefined */p { color: var(--main-text-color, var(--alternative-text-color, #006400));}
<article> <h1>Article's first heading 1 element</h1> <p>Article's first paragraph element</p> <h2>Article's first heading 2 element</h2> <p>Article's second paragraph element</p> <p>Article's third paragraph element</p></article>
Important Stuff to Know about the var()
CSS Function
1. Multiple fallbacks affect performance
Specifying more than one fallback argument may cause performance issues because browsers will require more time to parse the CSS variables.
2. Fallbacks do not fix browser compatibility
A fallback argument is not a way to fix browser compatibility. Instead, it is a backup value for browsers that support CSS variables.
In other words, a var()
function—including its arguments—will not work in browsers that do not support custom properties.
You can fix browser compatibility by declaring a regular CSS property before the declaration containing your var()
function.
Here’s an example:
:root { --main-text-color: #545aa7;}
p { color: #0000ff; color: var(--main-text-color, #0000ff);}
The snippet above provided the color: #0000ff
declaration for browsers that do not support CSS variables.
Note this:
The latest style declaration has higher specificity. Therefore, color: var(--main-text-color, #0000ff)
will override color: #0000ff
in browsers supporting CSS variables. But incompatible systems will ignore color: var(--main-text-color, #0000ff)
and use color: #0000ff
instead.
3. Local CSS variables override the global ones
Suppose you declared the same variable locally and globally. In such a case, the local declaration will override the global one.
Here’s an example:
/* Define your custom variables on the root element */:root { --primary-heading-color: blue;}
/* Use --primary-heading-color as the heading's text color */h1 { --primary-heading-color: red; color: var(--primary-heading-color);}
<article> <h1>Article's first heading 1 element</h1> <p>Article's first paragraph element</p> <h2>Article's first heading 2 element</h2> <p>Article's second paragraph element</p> <p>Article's third paragraph element</p></article>
In the snippet above, the local --primary-heading-color
variable in the <h1>
will override the global one in the :root
selector.
How to Access CSS Variables in JavaScript
Use the same JavaScript techniques for accessing regular CSS declarations to access custom properties.
Lets see some examples.
Example 1: Get an HTML element’s custom property
// Get the HTML element with a "first-article" id attribute:const articleElement = document.getElementById("first-article");
// Get the articleElement's computed styles:const computedStyles = window.getComputedStyle(articleElement);
// Get the --primary-heading-color CSS variable:const primaryHeadingColor = computedStyles.getPropertyValue( "--primary-heading-color",);
// Log the primaryHeadingColor's value on the browser's console:console.log(primaryHeadingColor);
/* Define your custom variables on the root element */:root { --primary-heading-color: #ff1493; --alternative-text-color: #e25822;}
/* Use --primary-heading-color as the heading's text color */h1 { color: var(--primary-heading-color);}
/* Use #006400 as the paragraph's text color if --main-text-color and --alternative-text-color are undefined */p { color: var(--main-text-color, var(--alternative-text-color, #006400));}
<article id="first-article"> <h1>Article's first heading 1 element</h1> <p>Article's first paragraph element</p> <h2>Article's first heading 2 element</h2> <p>Article's second paragraph element</p> <p>Article's third paragraph element</p></article>
Example 2: Get the CSS stylesheet’s custom property
// Get the document's zeroth indexed stylesheet:const zerothStylesheet = document.styleSheets[0];
// Get the zeroth indexed CSS ruleset:const zerothRuleset = zerothStylesheet.cssRules[0];
// Get the style declarations in the zeroth indexed ruleset:const cssStyleDeclarations = zerothRuleset.style;
// Get the --primary-heading-color CSS variable:const primaryHeadingColor = cssStyleDeclarations.getPropertyValue( "--primary-heading-color",);
// Log the primaryHeadingColor's value on the browser's console:console.log(primaryHeadingColor);
/* Define your custom variables on the root element */:root { --primary-heading-color: #ff1493; --alternative-text-color: #e25822;}
/* Use --primary-heading-color as the heading's text color */h1 { color: var(--primary-heading-color);}
/* Use #006400 as the paragraph's text color if --main-text-color and --alternative-text-color are undefined */p { color: var(--main-text-color, var(--alternative-text-color, #006400));}
<article> <h1>Article's first heading 1 element</h1> <p>Article's first paragraph element</p> <h2>Article's first heading 2 element</h2> <p>Article's second paragraph element</p> <p>Article's third paragraph element</p></article>
Use CSS Grid like a pro
How to Define CSS Variables in JavaScript
Use the same JavaScript technique for creating regular CSS declarations to define custom properties.
// Get the document's zeroth indexed stylesheet:const zerothStylesheet = document.styleSheets[0];
// Get the zeroth indexed CSS ruleset:const zerothRuleset = zerothStylesheet.cssRules[0];
// Get the style declarations in the zeroth indexed ruleset:const cssStyleDeclarations = zerothRuleset.style;
// Set the --heading2-color CSS variable:const heading2Color = cssStyleDeclarations.setProperty( "--heading2-color", "#3eb489",);
/* Define your custom variables on the root element */:root { --primary-heading-color: #ff1493; --alternative-text-color: #e25822;}
/* Use --primary-heading-color as the h1 heading's text color */h1 { color: var(--primary-heading-color);}
/* Use --heading2-color as the h2 heading's text color */h2 { color: var(--heading2-color);}
/* Use #006400 as the paragraph's text color if --main-text-color and --alternative-text-color are undefined */p { color: var(--main-text-color, var(--alternative-text-color, #006400));}
<article> <h1>Article's first heading 1 element</h1> <p>Article's first paragraph element</p> <h2>Article's first heading 2 element</h2> <p>Article's second paragraph element</p> <p>Article's third paragraph element</p></article>
Advantages of CSS Variables
1. CSS variables make stylesheets DRY of repeated values
CSS variables allow you to define a value once and reuse it on multiple elements. For instance, consider this stylesheet without CSS variables:
h1 { color: #000036;}
h2 { color: #000036;}
p { color: #000036;}
You can avoid the repetition of the #000036
value by using CSS variables like so:
:root { --primary-color: #000036;}
h1 { color: var(--primary-color);}
h2 { color: var(--primary-color);}
p { color: var(--primary-color);}
2. CSS variables make updating multiple values easier and faster
CSS variables make updating your declarations easier and faster because you no longer need to do a global search and replace. Instead, you would update only the custom properties.
3. CSS variables make CSS values easier to understand
Cascading variables allows values to be readable. For instance, it is easier to understand --primary-blue-color
than #436b95
.