DEV Community

Cover image for A Complete Guide To Using CSS Custom Variables
Uma Chisom Augustin
Uma Chisom Augustin

Posted on

A Complete Guide To Using CSS Custom Variables

Sometimes in CSS, values tend to show up multiple times or repeat themselves throughout your code. Imagine if you have a much bigger style sheet file, you will have to keep reusing these values again and again. That’s pretty stressful right?. Well, at some point, you might want to change every occurrence of a particular value. I know you may be asking “can’t i just do a find and replace?”. Doing a find and replace will work, but there is a much easier way you can change these values, and that is where CSS variables come in.

Outline

  • The Basics Of CSS Variables
    • What Are CSS Variables
    • Inheritance
    • Working with Invalid Variables and Fallback Values
    • Using CSS Variables With Inline Styles
    • Storing Single and Multiple Values
  • What You Should Know About CSS Variables
    • Using Variables With Media Queries
  • Conclusion

The Basics Of CSS Variables

What Are CSS Variables
CSS custom variables, also known as CSS variables or cascading variables, are entities that contain specific values that can be reused throughout a document. It is usually set using a custom property notion.

for example:

--main-color: black;
Enter fullscreen mode Exit fullscreen mode

and can be accessed using the var() function.

color: var(--main-color);
Enter fullscreen mode Exit fullscreen mode

When looking at the style sheet below, you will notice that there are some values of some elements that keep repeating themselves. For example, the border-radius, the color #0176b8 (which we have on the border of the button, background color, main color for our anchor tags, and down on the inverse button), and for the images we also use the width and height of 2.5rem.

.btn{
  text-decoration: none
  color: white
  background-color: #0176b8
  display:inline-block
  padding: 1px
  border-radius: 5px
  border: 1px solid #00176b8
}

.btn.inverse{
  background-color: white;
  border-color:#0176b8
  color: #0176b8
}

.table img{
  width: 2.5rem
  height: 2.5rem
  border-radius:50%
}
Enter fullscreen mode Exit fullscreen mode

Now, if you notice, these values show up, multiple times.

To get started, you have to define your variables inside the root pseudo-class, and this applies to the entire HTML document.

:root{

}
Enter fullscreen mode Exit fullscreen mode

To define a variable, you will have to start with a double hyphen, and then you input the name of the variable next. For instance color -primary; then put in the value. Lets say the #0176b8 color.

:root{
  --color-primary; #0176b8
} 
Enter fullscreen mode Exit fullscreen mode

You have now justified the variable by doing this. The next thing is to use the variable in your CSS code, by replacing that value with var, open parenthesis and then you put the name of your variable inside.

a{
  color: var(--color-primary);
}
Enter fullscreen mode Exit fullscreen mode

This will make all the anchor links, for example, to be defined by the variable. Remember that color #0176b8 is also the main color for the anchor tags. The awesome thing about this is that you can easily replace the value with another value. For instance, you can replace the color #0176b8 with let’s say Yellow, and all the elements that use that variable will get updated. Now instead of find and replace, you can just replace all the #0176b8 or colors in your CSS codes with your variable var(--color-primary);. Now if you change the color value, to let’s say yellow, every thing else changes to yellow. That’s pretty awesome, right?

:root{
  --color-primary; yellow
} 
Enter fullscreen mode Exit fullscreen mode

Let’s transform something else into a variable, like a border-radius for example. You can define another variable, by imputing borer-radius with 5pixels

:root{
  --color-primary; #0176b8
  --global-radius 5px;
} 
Enter fullscreen mode Exit fullscreen mode

All you have to do now is replace the border-radius with var(), global radius

.btn{
  text-decoration: none
  color: white
  background-color: #0176b8
  display:inline-block
  padding: 1px
  border-radius: var(global-radius);
  border: 1px solid #00176b8
}

.card {
    max-width: 50rem;
    background-color: white;
    padding: 2rem;
    border-radius: var(--global-radius);
    box-shadow: 1px 1px 15px 0 rgba(0, 0, 0, .25);
}
Enter fullscreen mode Exit fullscreen mode

If you go to - - border-radius and change the value from 5px to maybe 20px you will notice the cards and buttons updating automatically.

As for the case of browser compatibility, if you open caniuse, you can check the browsers that are compatible with the CSS variables, as shown in the image below:

CSS variables browser support

In this image, you can see that it is supported in most of the browsers, well except in internet explorer.

Inheritance
Inheritance controls what happens when there is no value specified for a property on an element;

<body>
  <div>
   <p>Hello</p>
  <h1>Text</h1> 
</body>
Enter fullscreen mode Exit fullscreen mode

Now, if you apply styles to the body tag, then everything within the body tag will inherit those styles. Let’s assume we want everything under the body tag to have a font color of blue, all you have to do is;

.body{
  color: blue;
}
Enter fullscreen mode Exit fullscreen mode

and everything under the body tag turns blue. Pretty cool right? well, that’s because everything within the body are inheriting that style. Let’s now say we want everything under the <div> tag to be yellow, you can do this:

.body{
  color: blue;
}
.div{
  color: yellow;
}
Enter fullscreen mode Exit fullscreen mode

and everything in the <div> tags overrides the inherited styles of the <body>tag, and turns yellow, while the rest remains blue. So! what if you want only the <p> tag to be green even though they already have the <div> tag of yellow. Well, you can just do this:

.body{
  color: blue;
}
.div{
  color: yellow;
}
.p{
  color: green;
}
Enter fullscreen mode Exit fullscreen mode

Working With Invalid Variables and Fallback Values

We are going to be learning what happens when certain CSS variables are invalid, and how the browser is going to deal with this, coupled with how to provide fallback values for CSS variables. Let’s get started!

<P> learning css variables<p>
Enter fullscreen mode Exit fullscreen mode

then inside the CSS, you can write this;

:root{
  --color: 1rem;
}
Enter fullscreen mode Exit fullscreen mode

As you can see, this is invalid, and we are going to see how the browser deals with it;

:root{
  --color: 1rem;
}
.body{
  display: flex;
  height: 100vh 
  align-items:center;
  justify-content: center:
}
.p{
  max-width: 50%
  color: var(--color);
}
Enter fullscreen mode Exit fullscreen mode

at this point, nothing happens because the color variable is invalid, i.e. it has an invalid value for the color property. Now, the browser checks if the color property can be inherited. So it looks at its parents to see if there is a color defined there. If you notice, the body, which is the parent element of the <P> tag does not have a color defined. In this case, the browser will go back to the initial value of the color, which is black, so the text still appears black. Even if you were to set a color of green in the

tag it still won’t work, because of the cascading nature of CSS. However, let’s say we defined color of blue in the body;

:root{
  --color: 1rem;
}
.body{
  display: flex;
  height: 100vh 
  align-items:center;
  justify-content: center;
  color: blue;
}
.p{
  max-width: 50%
  color: var(--color);
}
Enter fullscreen mode Exit fullscreen mode

Now, the text changes to blue, because we have defined the color off the body. If you remove the blue, the browser will automatically revert to the initial color, which is black. Hopefully, you understood this.

I am now going to show you how to define some fallback values for CSS variables. This is a simple mark up below;

<ul class="menu">
  <li><i class="far fa-bell"></i></li>
  <li><i class="far fa-bookmark"></i></li>
  <li><i class="far fa-calendar"></i></li>
</ul>
Enter fullscreen mode Exit fullscreen mode

then for the CSS, i added some demo styles for the body;

.body{
  display: flex;
  height: 100vh;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
  justify-content: center;
} 
Enter fullscreen mode Exit fullscreen mode

the next thing is to define our menu by defining some variables ;

.body{
  display: flex;
  height: 100vh;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
  justify-content: center;
} 

.menu{
  --item-size: 3rem;
  --font-size: 18px
  --item-color-1: black;
  --item-color-1: green;

  list-style:none
  padding: 0
  margin: 0
  display: flex;
  gap: calc(var(--item-size)/4);
  font-size: var(--font-size);
}
Enter fullscreen mode Exit fullscreen mode

trust me! it gets interesting from here. Now I am going to do this;

.body{
  display: flex;
  height: 100vh;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
  justify-content: center;
} 

.menu{
  --item-size: 3rem;
  --font-size: 18px
  --item-color-1: black;
  --item-color-2: green;

  list-style:none
  padding: 0
  margin: 0
  display: flex;
  gap: calc(var(--item-size)/4);
  font-size: var(--font-size);
}

.menu li{
  background-color:var(--item-color-1,red);
  color: white;
  width: var(--item-size);
  height: var(--item--size);
  text-align: center;
  line-height: var(--item-size);
  border-radius: 5px;
}
Enter fullscreen mode Exit fullscreen mode

Now, if you are going to use the var function like this, by adding a second parameter, what you are saying is, use item color 1 if it is defined, otherwise use the color red. So, if item color 1 was not defined, (--item-color-1, red); does not exist. You can even do;

.menu li{
  background-color:var(--item-color-2, blue));
  color: white;
  width: var(--item-size);
  height: var(--item--size);
  text-align: center;
  line-height: var(--item-size);
  border-radius: 5px;
}
Enter fullscreen mode Exit fullscreen mode

what this means is that, you can say var(), and inside the var() you are saying, if item color 1 does not exist, then use item color 2 and if that does not exist, use another color, e.g. blue; if item color 1 was not defined, it uses item color 2. If item color 2 was not defined, it uses the fallback which is blue.

Note that this is not a solution for invalid variables. Therefore, you cannot use this fallback to fix invalid variables.

Using CSS Variables With Inline Styles

Using inline styles in production is not recommended in the final stages of your code, but it can break the CSS specificity that you defined in your style sheet. Although, you can use inline styles during development or testing. So, I will be showing you how variables can help you. Lets’ check out the simple grid i designed below in HTML;

<div  class= "grid">
  <div class= "grid-item">
    <img src="https://media.istockphoto.com/photos/advertising-concept-confident-and-smiling-young-african-american-picture-id1290599844?b=1&k=20&m=1290599844&s=170667a&w=0&h=mKM_VHxQK1N0l5ojPiG9mcIRERgt4RqMqfP5Z9hnKN8= "> 
    </div>


    <div class= "grid-item">
      <img src="https://media.istockphoto.com/photos/advertising-concept-confident-and-smiling-young-african-american-picture-id1290599844?b=1&k=20&m=1290599844&s=170667a&w=0&h=mKM_VHxQK1N0l5ojPiG9mcIRERgt4RqMqfP5Z9hnKN8= "> 
      </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Then i have the CSS;

.grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--column-width), 1fr));
  grid-gap:var(--gap);
  margin-button 2rem;
}

.grid-item{
  background-color: #705ae3;
  color: white;
  display:flex;
  align-item: center;
  justify-content:center;
  padding: 2rem;
}

.img{
  width: var(--avatar-size);
  height: var(--avatar-size);
  border-radius: 50%
  border: 2px solid white;
}
Enter fullscreen mode Exit fullscreen mode

all you have to do here is define the actual variables, and we are going to define them in the root;

:root{
  --avatar-size: 3rem;
  --column-width: 20rem
  --gap: calc(var(--column-width)/ 10);

}
Enter fullscreen mode Exit fullscreen mode

Now, let’s say during development or during testing, you can play around with different values for the grid, without opening up the CSS file again. You can do this from your browser or HTML using inline styles, as seen in the example below;

<div  class= "grid" style="--column-width: 12rem">
  <div class= "grid-item">
    <img src="https://media.istockphoto.com/photos/advertising-concept-confident-and-smiling-young-african-american-picture-id1290599844?b=1&k=20&m=1290599844&s=170667a&w=0&h=mKM_VHxQK1N0l5ojPiG9mcIRERgt4RqMqfP5Z9hnKN8= "> 
    </div>


    <div class= "grid-item">
      <img src="https://media.istockphoto.com/photos/advertising-concept-confident-and-smiling-young-african-american-picture-id1290599844?b=1&k=20&m=1290599844&s=170667a&w=0&h=mKM_VHxQK1N0l5ojPiG9mcIRERgt4RqMqfP5Z9hnKN8= "> 
      </div>
</div>
Enter fullscreen mode Exit fullscreen mode

You can now play around with the size here. For instance, you can change the size from 12rem to 15rem, depending on which one you want to work with. Why this is cool is because you don’t have to change anything in your CSS file. Note, please do not use this in your final code.

Storing Single and Multiple Values
In this lesson, you will learn about what values you can store inside a CSS variable. You will see that you can store multiple values in the same variable. Let’s start with this simple HTML, which is a card with a paragraph and a button inside;

<div class="card">
  <h1> How are you today</h1>
  <p> i am fine thank you</p>

  <a href="a" class="btn">close window</a>
</div>
Enter fullscreen mode Exit fullscreen mode

let’s write the CSS;

.body{
   display:flex;
   height: 100vh
   align-items: center;
   justify-content: center:
   background-color: #ececec;
   line-height: 1.35;
}
Enter fullscreen mode Exit fullscreen mode

CSS variables are not just for holding numbers, pixel values, or colors. They are also capable of holding gradients for example;

:root{
  --body-bg: linear-gradient(120deg, #705ae3 0%, #8ec5fc 100%);
}

.body{
   display:flex;
   height: 100vh
   align-items: center;
   justify-content: center:
   background-color: #ececec;
   line-height: 1.35;
}
Enter fullscreen mode Exit fullscreen mode

now you can go into your body and say;

:root{
  --body-bg: linear-gradient(120deg, #705ae3 0%, #8ec5fc 100%);
}

.body{
   background-image: var(--body-bg);
   display:flex;
   height: 100vh
   align-items: center;
   justify-content: center:
   background-color: #ececec;
   line-height: 1.35;
}
Enter fullscreen mode Exit fullscreen mode

as i stated above, variables are capable of holding multiple values, i will be demonstrating with another example using button color;

:root{
  --body-bg: linear-gradient(120deg, #705ae3 0%, #8ec5fc 100%);
  --button-color: 107, 93, 227;
}

.body{
   background-image: var(--body-bg);
   display:flex;
   height: 100vh
   align-items: center;
   justify-content: center:
   background-color: #ececec;
   line-height: 1.35;
}

.btn{
  background-color: rgb(var(--button-color));
  display: inline-block;
  color: white;
  padding: 1rem 2.5rem;
  text-decoration:none;
  border-radius: 100px;
}
Enter fullscreen mode Exit fullscreen mode

as you can see, you can use the 107, 93, 227; and define the color as rgb.

What You Should Know About CSS variables

Using CSS Variables With Media Queries and JavaScript
In this lesson, you are going to learn how to use CSS variables inside media queries, and how to change their value with JavaScript. For the HTML, we are going to use a simple grid;

<div class="grid">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">5</div>
</div>
Enter fullscreen mode Exit fullscreen mode

for the CSS;

.body{
  padding: 2rem;  
}

.grid{
  --grid-item-color: #8ec5fc
  --column-width: 100%;
  --gap: 1rem;

  display: grid;
  grid-template-column: repeat(auto-fill, minmax(var(--column-width),1fr));
  grid-gap: var(--gap);
}

.grid-item{
  background-color: var(--grid-item-color);
  color: white;
  display: fle;
  align-items: center;
  padding: 2rem;
}
Enter fullscreen mode Exit fullscreen mode

Now, this version of the grid will work on all screen sizes, but what if you want to split up into multiple columns when it reaches or surpasses a certain screen width, all you have to do is use media query, as shown in the example below;

.body{
  padding: 2rem;  
}

.grid{
  --grid-item-color: #8ec5fc
  --column-width: 100%;
  --gap: 1rem;

  display: grid;
  grid-template-column: repeat(auto-fill, minmax(var(--column-width),1fr));
  grid-gap: var(--gap);
}

.grid-item{
  background-color: var(--grid-item-color);
  color: white;
  display: fle;
  align-items: center;
  padding: 2rem;
}

@media screen and (min-width: 720px) {
  .grid{
     --column-width: 10rem;
     --gap: calc(var(--column-width)/ 10);
  }
}
Enter fullscreen mode Exit fullscreen mode

Now, when we go past 720 pixels, you see the changes in the grid from the stacked version to using actual columns, all thanks to the media query. Now, what about JavaScript, you can read CSS variables from JavaScript, and you can change the color. Let me show you in the example below;

let targetElem = document.querySelector('.grid');
targetElem.style.setProperty('--grid-item-color', 'purple');
Enter fullscreen mode Exit fullscreen mode

Now, you can see that when we go back to the original code, i.e. the one outside the media query, it actually changes the color to whatever color you want, you can change the ‘purple’ color to ‘yellow’.

Conclusion
What I have done in this article, is to explain what CSS variables mean, and how to use them in your style sheet file. In the aspect of web development, speed and flexibility is very important, and CSS variables helps with these.

If you implement your CSS variables properly, it will make your code more readable and accessible, and still provide a semantic meaning to your values.

Top comments (0)