Get the 2024 Yearly Goals and Progress Tracker Notion Template for FREE!

Using CSS Variables like a Pro: A Beginners Guide to the var() CSS Function

SERIES: The Deep Dives

Updated on: Dec 23, 2023

19 mins read


CSS variables help you to create custom CSS styles that can be reused continuously throughout your document or website. This is done using the CSS `var()` function.

Using CSS Variables like a Pro: A Beginners Guide to the var() CSS Function

Prerequisites

I assume you already know how to style your HTML documents using CSS.

And with that on the confirmation,

lady "saying let's get started"

Image by Giphy

What are CSS Variables?

Imagine creating a website with a large CSS code base and complexity, and you have a brand color of Red and Green, which would be reused several times throughout the website. You decide to use Red as the primary color, finish building the website, and show it to your client, but the client says he would have preferred Green instead. So you have to return to all the instances you used Red and then change them to Green. That sounds stressful, doesn't it, especially if the number of those instances is 20, 100, or even more.

Now imagine if you had used a CSS variable instead to declare the value of the color Red, and you had called that variable in all those instances. Then, when the client decides to go with Green, all you have to do is change the color value in one place (i.e., where you declared it), and just like that, all the Reds suddenly become Green. Magical, isn't it. Not really; it's just the power of CSS variables.

man saying "magic" with razzle dazzle hands

Image by Giphy

According to MDN :

Custom properties (sometimes called CSS variables or cascading variables) are defined by CSS authors that contain specific values to be reused throughout a document.

CSS variables help to make the reuse of stylings a lot easier. All you have to do is declare it once and call it anywhere you want to use it. This makes it easier to maintain your codebase and also makes it easier to change the variable's value if need be.

Now that you know what it's about, let's discuss how we can use it.

CSS Variable Syntax

The syntax is quite simple and uses a CSS var() function. To define variables in CSS, you must first declare the CSS variables you want to use within the selector.

css
/* Syntax */
selector {
--variable-name: value;
}
/* Example */
:root {
--main-color: red;
}

A variable in CSS must begin with two dashes (--) and is case-sensitive! This means that --main-color is not the same as --Main-color or --main-Color. The browser will treat the above 3 as different custom properties.

The next step is to call the variable within the elements that will use it using the var() function.

css
/* Syntax */
element {
style: var(--name, value);
}
/* Example */
button {
color: var(--main-color, blue);
}

The value is optional and is known as a fallback value. We will discuss this in detail later on.

Scoping of CSS Variables

Variables in CSS can be used in any CSS selector. The selector type would determine if the variable would have a global or local scope and become a global or local variable.

The global variables can be used by every element in the document, while local variables can be used only by the elements inside the selector where it is declared.

To create a variable with a global scope, declare the CSS variable inside the :root selector. The :root selector represents the document's root element.

To create a variable with a local scope, declare it inside the selector that will use it.

Key Point:

It is custom practice to define CSS variables in the :root, but a few cases warrant you having them in a local scope.

Global and Local Scope of CSS Variables

Now that we understand the basics of CSS variables let's delve into the concept of scope, which plays a crucial role in how these variables are accessed within your stylesheets.

Global Scope: :root Selector

CSS variables, sometimes called CSS root variables, can be declared with global scope, making them accessible to every element in the document. This is typically done by declaring the variables within the :root selector, representing the document's root element.

css
:root {
--global-color: #3498db;
--global-font-size: 16px;
}

Here, we've declared two variables, --global-color and --global-font-size, with global scope. These variables can now be used anywhere in your stylesheets, providing consistent and easily updated styling across the entire document.

Local Scope: Within Selectors

In contrast, CSS variables can also be declared with local scope, limiting their accessibility to specific elements or selectors. Let's say you want to define a specific color palette for a particular section of your website:

css
.section-container {
--section-background: #f2f2f2;
--section-text-color: #333;
}
.section-container .section-content {
background-color: var(--section-background);
color: var(--section-text-color);
}

In this example, the variables --section-background and --section-text-color are declared within the .section-container selector, confining their scope to elements within that specific container. This allows you to create modular and encapsulated styles, preventing unintended style conflicts with variables in other parts of your document.

Understanding and effectively utilizing global and local scope in CSS variables empower you to manage styling with flexibility and ease, enhancing the maintainability of your codebase.

Global vs Local Scope of CSS Variables

CSS Variable Fallback Value

The purpose of a fallback value is that if, for any reason, the browser cannot access and use the variable, the browser should use this instead. So if our variable, --main-color, cannot be used, the browser should use blue.

An instance would be if we

  • made a spelling error when declaring our CSS variable name or when calling it.
  • are calling a variable that is out of the scope it is being used in.
  • forgot to declare the variable in the first place.
css
:root {
--main-coor: red;
}
button {
color: var(--main-color, blue);
}

Therefore, if the browser cannot access our variable because it cannot find its declaration anywhere, it should use blue as the next best thing.

If the browser still cannot access the fallback value after you did not give it a value to fall back on or you again made a spelling error, then you are on your own oh.

man saying "only God Can Save You"

Image by Giphy

man saying "just Kidding"

Image by Giphy

The browser will look into the styles of the parent element to find if the property value is given there. If it's not, it then looks into the next parent element and on and on, going up until it has no more parent element and results back to its initial value, so it would be looking for styles for it to inherit. The browser returns the element's default property value if it doesn't find one.

html
<body>
<div class="outer-div">
<div class="inner-div">
<h1>Title</h1>
<p>paragraph</p>
</div>
</div>
</body>
css
.outer-div {
color: green;
}
.inner-div {
color: red;
}
p {
--coor: blue;
color: var(--color, blu);
}

You can see here that we are trying to make our p element have a color blue, but because we did not declare the variable and also misspelled the fallback value, it then inherits the red color from its parent .inner-div. If you were to comment out the .inner-div color, the paragraph would then be a color of green gotten from the .outer-div, and if you were to comment that out again, the paragraph would now have a color of black, which is the default color it would inherit from the body.

But mind you, if you were to give the body a color of orange, the paragraph would be orange instead of black.

CSS Variable Fallback Value

It's all about Inheritance.

Let's give another example of this.

Inheritance in CSS Variables

The CSS variables of an element can be inherited by its children if the children do not have their own stylings or custom properties applied to them. Or, in the case of the example above, have a spelling error. Ultimately, these children would inherit the style property of its parent.

html
<div class="one">
<div class="two">
<div class="three"></div>
<div class="four"></div>
</div>
</div>
css
.two {
--test: 20px;
font-size: var(--test);
}
.three {
--test: 2em;
font-size: var(--test);
}

From the example above, the class="two" element gets a font size of 20px, which should be inherited by its children.

The class="four" element gets a font size of 20px, which it has inherited from its parent, class="two" element.

But the class="three" element, on the other hand, gets a font size of 2em because the value of the declared variable has now been changed within the child element.

CSS Variable Inheritance Example

Specificity in CSS Variables

The same way specificity works in CSS is how it works with variables.

For example, you declare a variable color twice in the same selector, firstly as red, then second as green, and then call the variable in your p element. Which color would the p element be?

css
div {
--color: red;
--color: green;
}
p {
color: var(--color);
}

If you guessed green, then you are right. While going through the code, the browser would first save the variable as red, then when it sees that the variable is again declared a second time with another value, it saves the value to green. When it then finds a call for it—in our case, the p element—, it gives it a green color.

From the example given in the inheritance section above, you can see that the CSS variable declared in the child element takes precedence over the same CSS variable that was declared in its parent element.

CSS Variable Validity

When the value of a CSS variable is not valid for the property of the element it is being called in, it either inherits a new value or has its initial value used.

a minion saying 'whaaaaaaaaaat!'

Image by Giphy

Lemme further explain this.

A CSS variable, when declared, would initially have its value said to be valid. Here, the browser has not found any need for it to be used in any element yet, so it would have no choice but to call it valid and store it as a valid value for a CSS variable.

But when it gets to an element where it is to be used, i.e., being declared, and finds out that the value being given by the variable is not a value that is acceptable as a property value, that value then becomes invalid, thus making the variable invalid.

This does not mean that the declaration of the variable in itself is invalid, but in the instance where the browser tried to use it and failed, it becomes invalid only in that element property and in any other whose element property cannot use the value. In that instance, the browser would then look into its parent element to find a value to use or, in the end, use its initial value. It wouldn't even bother looking for a fallback value.

Lemme explain with an example.

html
<div>
<p class="p1">This paragraph inherits the color green.</p>
<p class="p2">This paragraph is blue.</p>
<p class="p3">This paragraph is still blue.</p>
</div>
css
:root {
--font-size: 20px;
}
div {
color: green;
}
p {
color: blue;
}
.p1 {
color: var(--font-size, blue);
font-size: var(--font-size);
}
.p3 {
color: 16px;
}

The browser first stores the --font-size as a valid value of 20px. Then, it gives all the paragraphs a blue color, as declared in the p selector. It then moves to the p element with a class of p1, sees that the variable it has stored is being called, and then tries to use it.

The browser is expected to take the value of our CSS variable --font-size and substitute it in our .p1 element. Still, since 16px is not a valid property value for color, the value becomes invalid because it doesn't make sense to the browser. The browser then handles this situation in two ways:

  • It checks if the property color is inheritable. Seeing that it is, it then looks for a parent element, in this case, the div element, and finds that there is a color property value the p element can inherit. So now the paragraph gets a green color.
  • In the case whereby the element does not have a parent element or its parent element does not have a property value it can inherit, the browser then sets the value back to its default initial value, i.e., black, ignoring the fallback value.

But if you had written color: 16px; instead of color: var(--font-size); then the browser would have viewed that as a syntax error, and the previous declaration of color: blue; on the p element would then be used.

Remember that we also used that same variable as a value for the font size for the same element. Would the font size of our .p1 element change or not?

man calculating

Image by Giphy

Yes, it would. This is because the 16px value of our CSS variable is now a valid value for the font size property.

As you can see, the variable was only invalid when we tried to use it as a value for our color but became valid once more when we used it as a value for our font size.

CSS Variable Validity

Browser Compatibility of CSS Variables

CSS variables are widely supported across modern browsers, including Google Chrome, Mozilla Firefox, Apple Safari, Microsoft Edge, and Opera. However, it's important to note that Internet Explorer does not support CSS variables. If compatibility with older browsers is a requirement, consider using CSS preprocessors like Sass or Less, which provide similar functionality and can be compiled into standard CSS.

When implementing CSS variables, adopting a progressive enhancement approach is recommended. This involves using CSS variables where supported and providing fallbacks or alternative styles for browsers that lack support. Regularly check browser compatibility and adjust strategies to ensure a consistent user experience across different environments. You can stay informed about the current state of browser support through resources like caniuse.com.

Advanced Use Cases for CSS Variables

CSS variables offer versatility beyond basic styling. One advanced use case is dynamic updates using JavaScript. Imagine creating a dark mode feature where the color scheme changes dynamically. Here's a simple example:

css
/* CSS */
:root {
--main-bg-color: #ffffff; /* default light mode */
}
body {
background-color: var(--main-bg-color);
}
js
// JavaScript
// Toggle between light and dark mode
document.querySelector("body").addEventListener("click", () => {
const body = document.querySelector("body");
body.style.setProperty(
"--main-bg-color",
body.style.getPropertyValue("--main-bg-color") === "#ffffff"
? "#1a1a1a"
: "#ffffff"
);
});

In this example, we've created a CSS variable --main-bg-color to store the background color of the body element. The default value is #ffffff, representing the light mode. When the body is clicked, the background color is toggled between light and dark mode by changing the value of the CSS variable.

Creating a dark mode feature using CSS variables

Other use cases include:

  • Responsive Design: CSS variables can be used to create responsive designs that adapt to different screen sizes. For example, you can define a variable for the font size and change the value based on the screen width.
  • Animations: CSS variables can be used to create dynamic animations. For instance, you can define a variable for the animation duration and change the value to speed up or slow down the animation.
  • Dynamic Styling: CSS variables can dynamically style elements based on user interactions. For example, you can define a variable for the background color and change the value when the user hovers over an element.
  • Collaboration with JavaScript: CSS variables can be used with JavaScript to create interactive designs. For example, you can define a variable for the background color and change the value based on user input.

Feel free to explore more scenarios where CSS variables and JavaScript collaboration can bring your designs to life.

Best Practices for Using CSS Variables

While CSS variables boost maintainability, adopting best practices ensures a seamless development experience. Follow these tips:

  • Clear Naming: Choose descriptive names for variables to enhance readability. Avoid generic names like --color or --size that can be easily confused with other variables. Instead, use names like --main-color or --font-size to provide clarity.
  • Organized Declaration: Consider declaring variables in a separate CSS file to keep your styles organized. This also makes it easier to manage and update variables across multiple documents.
  • Global vs. Local: Reserve global variables for widely used values and opt for local variables when styling specific components. This helps to prevent unintended style conflicts and improves code maintainability.
  • Consistency: Maintain a consistent naming convention and usage pattern across your project. For example, if you declare --main-color in one place, don't decleare --main-color in another place. Instead, use --main-color consistently throughout your project.
  • Documentation: Document your variables to provide context and usage instructions for other developers. This is especially important for global variables, which can be used in many places throughout your document.
  • Code Review: Review your code to ensure variables are used correctly and consistently.

These practices contribute to code clarity and ease of collaboration among developers.

Common Pitfalls When Working with CSS Variables

Despite their power, CSS variables come with their share of pitfalls. Avoid these common mistakes:

  • Invalid Values: Ensure that variable values match the expected data type for the property they modify. For example, a color variable should be a valid color value.
  • Variable Redefinition: Be cautious when redefining variables within the same selector, as the last declaration takes precedence. This can lead to unexpected behavior like the specificity issue discussed earlier.
  • Fallback Strategy: Always provide fallback values to prevent unexpected styling issues in case variables are inaccessible. This is especially important for global variables, which can be used in many places throughout your document.
  • Variable Scope: Be mindful of variable scope when declaring variables. Global variables can be accessed by any element in the document, while local variables are limited to specific selectors. This can lead to unexpected styling conflicts if not managed properly.
  • Browser Support: Internet Explorer does not support CSS variables. If compatibility with older browsers is a requirement, consider using CSS preprocessors like Sass or Less, which provide similar functionality and can be compiled into standard CSS.

By steering clear of these pitfalls, you'll harness the full potential of CSS variables without stumbling into avoidable errors.

Recap on CSS Variables

And that's basically everything you need to know about CSS variables. Let's do a quick recap.

  • CSS variables help you to create custom CSS styles that can be reused continuously throughout your document or website.
  • They can either be globally scoped or locally scoped.
  • To use a CSS variable, you have to declare the variable in a selector, which is usually in the :root CSS selector, and then call the variable in the element(s) you wish to use it in.
  • A fallback value is a property value to be used if the CSS variable cannot be accessed and used by the browser for any reason.
  • Css variables of an element can be inherited by its children. This is if the children do not have their own stylings or custom properties applied to them.
  • A variable can become invalid if its value is not a property of the style that is being applied. The property either then inherits the value of its parent element or goes back to its initial value when the value of the CSS variable becomes invalid.
  • CSS variables can be used in conjunction with JavaScript to create interactive designs.
  • CSS variables boost maintainability, and adopting best practices ensures a seamless development experience.
  • Despite their power, CSS variables come with their share of pitfalls. Avoid these common mistakes.
  • CSS variables are widely supported across modern browsers, including Google Chrome, Mozilla Firefox, Apple Safari, Microsoft Edge, and Opera. However, it's important to note that Internet Explorer does not support CSS variables.

And that wraps it up on the magic that is CSS variables. I hope you found it insightful and enjoyed reading it. Please share this with your friends if you did.😁

Till next time, guys. Bye!

man smiling and waving goodbye

Image by

GIPHY

Connect With Me

Follow me on X(Twitter), and LinkedIn to stay updated with my latest content.

If you like my notes and want to support me, you can sponsor me on GitHub Sponsor, or you can buy me a virtual ice cream on ByMeACoffee or Selar. I would really appreciate it. 🙏

For other ways to support me, visit my Sponsorship page or Affiliate Links page.

Frequently Asked Questions

1. What are CSS variables?

CSS variables, or custom properties, are entities CSS authors define to store reusable values. These values can be used throughout a document or website, providing a flexible way to manage and apply consistent styles. CSS variables are declared using the :root selector for global scope or within specific selectors for local scope.

2. How to define variables in CSS?

To define variables in CSS, you use the following syntax:

:root {
  --variable-name: value;
}

For example:

:root {
  --main-color: red;
}
3. Can I use CSS variables in HTML?

Yes, you can use CSS variables in HTML. To do this, you reference the variables using the var() function within your HTML elements' style attributes or in your style sheets. For example:

<div style="--main-color: blue; background-color: var(--main-color);">
  This div has a background color defined by a CSS variable.
</div>
4. What are CSS root variables?

CSS root variables are variables declared within the :root selector, representing the document's root element. These variables have a global scope, making them accessible to all elements in the document. Global variables are useful for defining values that need to be reused across various selectors.

5. Can I set CSS variables from JavaScript?

Yes, you can set CSS variables from JavaScript. Use the setProperty method on the style property of an element to dynamically change the value of a CSS variable. For example:

// Get the root element
var root = document.documentElement;

// Set the value of the --main-color variable to blue
root.style.setProperty]('--main-color', 'blue');
6. How to use CSS variables in React?

You can use CSS variables in React by referencing them in your component or inline styles. Using a CSS-in-JS solution like styled-components, you can interpolate the variables directly into your styles. Ensure that the variables are either defined globally or scoped to the component where they are used.

7. Basic CSS cascading with variables

CSS variables follow the standard cascading rules in CSS. The local definition takes precedence if a variable is defined globally and locally. Understanding the cascading behavior is crucial for managing the scope and value of variables in different parts of your stylesheets.

8. What is the use of `var` in CSS?

The var in CSS is not to be confused with the CSS variable itself. It is a function, var(), used to reference and apply the value of a CSS variable. When you use var(--variable-name) in your styles, it pulls in the value assigned to the specified variable, providing a dynamic and reusable way to manage styles across your document.

9. What is a CSS Variable Selector?

In CSS, there is no specific "CSS Variable Selector." Instead, CSS variables, also known as custom properties, are declared and accessed using a custom property notation. The custom property notation starts with two hyphens (--) followed by the property name. For instance, if you want to create a variable for the main color, you would declare it like this:

:root {
--main-color: #3498db;
}

You can then use this variable throughout your stylesheets with the var() function.

Subscribe to my newsletter 💌

Never miss a beat! Stay updated with my latest tech tutorials, code snippets, how-to guides, productivity tips, personal projects and experiences, and more! 💻📚✨