A Complete Guide To Using CSS Custom Variables
Published: 2022-02-28 07:00:58


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;

and can be accessed using the `var()` function.


    color: var(--main-color);

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%
    }


 
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{
      
    }

 
 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
    } 

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);
    }

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
    } 

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;
    } 

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);
    }
     


 
  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](https://caniuse.com/), you can check the browsers that are compatible with the CSS variables, as shown in the image below:

![CSS variables browser support](https://paper-attachments.dropbox.com/s_32F4C3824881692A20428E8D0911DEB937E37475109443D9D6A37E5C70B94146_1645427684000_Screenshot+from+2022-02-21+07-49-18.png)


 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>

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;
    }

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;
    }

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;
    }

**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>

then inside the CSS, you can write this;


    :root{
      --color: 1rem;
    }

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);
    }

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 <p> 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);
    }

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>

 
 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;
    } 

 
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);
    }

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;
    }

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;
    }

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>
        

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;
    }

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);
      
    }

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>
        

 
 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>

let’s write the CSS;


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

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;
    }

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;
    }

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;
    }

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>

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;
    }

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);
      }
    }
    

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');

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.