CSS Variables

This write-up is taken from the beautifully built course here: https://scrimba.com/g/gcssvariables

CSS Variables are specific values to be reused throughout a document. They make your CSS more readable and make it more efficient for making changes later on in big documents.

Let's see how to use and create our own CSS Variables.

Below is a basic layout which we will change using CSS Variables.

Here is what only the CSS pertinent to learning about variables looks like


html, body {
    
}

h1, p {
    
}

#navbar a {
    
}

.item {
    
}

button {
    
}

Let's give it some color

html, body {
    background: #ffeead;
    color: #ff6f69;
}

h1, p {
    color: #ff6f69;
}

#navbar a {
    color: #ff6f69;
}

.item {
    background: #ffcc5c;
}

button {
    background: #ff6f69;
    color: #ffcc5c;
}

Now we can create our FIRST CSS Variable

Let's make our color #ff6f69 (red) a CSS Variable by putting a :root in our code like this.

:root {
    --red: #ff6f69;
}

Wherever you are using that color in your code you can now replace #ff6f69 with this var(--red)

So your code should look like this now.

html, body {
    background: #ffeead;
    color: var(--red);
}

h1, p {
    color: var(--red);
}

#navbar a {
    color: var(--red);
}

.item {
    background: #ffcc5c;
}

button {
    background: var(--red);
    color: #ffcc5c;
}

We can do the same thing with the rest of the colors.

:root {
    --red: #ff6f69;
    --beige: #ffeead;
    --orange: #ffcc5c;
}

html, body {
    background: var(--beige);
    color: var(--red);
}

h1, p {
    color: var(--red);
}

#navbar a {
    color: var(--red);
}

.item {
    background: var(--yellow);
}

button {
    background: var(--red);
    color: var(--yellow);
}

Check out our page!

Pretty cool

Now if you want to change the red everywhere on your page, you just have to change it in the root and it will change everywhere, instead of having to change it at each location it is being used at.

:root {
    --red: blue;
    --beige: #ffeead;
    --yellow: #ffcc5c;
}

Overriding Variables

The :root will select our <html> tag and everything inside of it, or in other words, our entire document. But what if we wanted only certain sections of our code to be, for example, a lighter red than the rest.

Here is my HTML page so that you can understand what is being selected.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>CSS Variables</title>
        <link rel="stylesheet" href="index.css">
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <header>
            <nav id="navbar">
                <ul>
                    <li><a href="#">home</a></li>
                    <li><a href="#">about</a></li>
                    <li><a href="#">contact</a></li>
                </ul>
            </nav>
        </header>
        <main>
            <h1>my awesome portfolio</h1>
            <div class="grid">
                <div class="item">
                    <h1>project a</h1>
                    <button>learn more</button>
                </div>
                <div class="item">
                    <h1>project b</h1>
                    <button>learn more</button>
                </div>
                <div class="item">
                    <h1>project c</h1>
                    <button>learn more</button>
                </div>
                <div class="item done">
                    <h1>project d</h1>
                    <button>learn more</button>
                </div>
            </div>
        </main>
        <footer><p>Made with ☕ in Norway</p></footer>
    </body>
</html>

Let's select just the item class and override the red variable for just those sections.

We will go into .item and make the following changes

.item {
    --red: #ff8e69;
    background: var(--yellow);
}

Our page will now look like this

Notice the lighter red in only the .item sections of the page.

Take note that the variables are inherited down to the children elements.

Local Variables

This time we are going to be creating a variable that is specific to only one element.

We will add in a #navbar to our css and make a change to our #navbar a like this:

#navbar {
    --nav-red: #ff6f19;
}

#navbar a {
    color: var(--nav-red);
}

Our page will now look like this

You will notice that the items in the navbar have been changed to a different shade of red/orange than the rest.

If we now try to use --nav-red in any other part of our code then it will break our code.

Themes

Basically this is the exact same as just overriding colors but it demonstrates a more practical use of CSS Variables.

We will build a class called featured and use it as a specific theme.

.featured {
    --yellow: #ffe55b;
    --red: #ff5564;
}

These are different than the :root defined yellow and red colors. But now all we have to do is add featured as a class to anything we want and it will take on this theme.

<main>
            <h1>my awesome portfolio</h1>
            <div class="grid">
                <div class="item featured">
                    <h1>project a</h1>
                    <button>learn more</button>
                </div>
                <div class="item">
                    <h1>project b</h1>
                    <button>learn more</button>
                </div>
                <div class="item">
                    <h1>project c</h1>
                    <button>learn more</button>
                </div>
                <div class="item featured">
                    <h1>project d</h1>
                    <button>learn more</button>
                </div>
            </div>
        </main>

Which will now look like this

Changing Variables with JavaScript

Something that you cannot do with Sass or
Less Variables is change variables with JavaScript. Since CSS Variables are working with the DOM we have this option available to us.

Create a new file and call it index.js and put the code below inside of it.

var root = document.querySelector(':root');
//selects our root element aka the whole DOM
var rootStyles = getComputedStyle(root);
var red = rootStyles.getPropertyValue('--red');
console.log('red: ', red);
//These last three lines are just to display that we have accessed the color directly.

root.style.setProperty('--red', 'green')
//this line is doing the actual changing of our color

You will notice that our page now has changed all instances of var(--red) into the color green, which in this case is just the title since the rest have been overridden.

Responsiveness

I've added some CSS Grid to our CSS file. If you are unfamiliar with CSS Grid just go checkout the writeup on located here

:root {
    --red: #ff6f69;
    --beige: #ffeead;
    --yellow: #ffcc5c;
}

html, body {
    background: var(--beige);
    color: var(--red);
}

h1, p {
    color: var(--red);
}

#navbar a {
    color: var(--nav-red);
}

.item {
    background: var(--yellow);
}

button {
    background: var(--red);
    color: var(--yellow);
}

.grid {
    display: grid;
    grid-template-columns: 200px;
    grid-auto-rows: 140px;
    grid-gap: 20px;
    justify-content: center;
}

The problem we will be addressing is the fact that if we make our screen smaller than 450px it starts to cut off some of our boxes.

just add the following changes to our css

.grid {
    --columns: 200px 200px;
}
... at the top of page usually

.grid {
    display: grid;
    grid-template-columns: var(--columns);
    grid-auto-rows: 140px;
    grid-gap: 20px;
    justify-content: center;
}

@media all and (max-width: 450px){
    .grid {
        --columns: 200px;
    }
}

Now when we make our page small it looks like this

If you want to practice and follow along to a screencast, just follow this link