Theming with native CSS variables
Tags: css, html, beginners, theme
Published: 2021-04-08 16:49:52

When developing Frontend, I'm pretty sure most of us make have used something like Bootstrap or Bulma.io, they give us tools to create beautiful interfaces with just a handful of classes added into our HTML elements.

Among one of the many things we can find are the Themes, that let us change the whole look of our elements with just a few lines of code or just adding a simple class. There are many ways of achieving this but in this case I want to share how I prefer to create these Themes and with the use of CSS Variables.

## What are CSS variables?  

CSS variables, as its name implies, are variables that we can be assigned a value and then use it later, but one of the most important things is that its value can be changed and it will affect in cascade anything that is using it from the point we change the value, just as CSS is supposed to work. CSS variables are completely different from those we have on a preprocessor, so we don't need those preprocessor variables for us to create a simple theme.

## Let's start with our Theme

Now that we know what a CSS variables is, we can start creating our Theme, so first we are going to create some variables. CSS variables follow this syntaxis `--my-var: value`.  To declare our variables as global variables, we have to declare them in the `:root` so we declare them as follows:


```
:root {
  --main: #110066;
  --secondary: #90CBFB;
  --button-text: #FFF;
}
```
We can declare variables inside classes, but for now, let's just have this three as global.

Now that we have our variables declared, we can use them as we please, so we are going to create some buttons using those variables:

```
.button {
  padding: .5em 1em;
  border-radius: .5em;
  background-color: var(--main);
  color: var(--button-text);
  display:inline-block;
}
```
We have our main button and to add a secondary button we just change or `background-color` and use the `--secondary` variable:

```
.button.secondary {
  background-color: var(--secondary);
}
```
We are going to call these classes our default Theme, since they don't need anything else to be styled, just add those classes to the element, so we are going to add just two simple anchors.

```
<div class='theme'>
  <a class='button'>Main Button</a>
  <a class='button secondary'>Secondary Button</a>
</div>
```
If everything went well, we should see something like this:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h126zvt06zju86p8thss.png)

If we wanted, we could use those variables for anything else, like `border-color`, but just to keep it simple we are just changing the `background-color`.

Just to add more variety to our theme we are going to add a message element:

```
<div class='theme'>  
  .
  .
  .
  <div>
    <span class='message'>
      This is my main Message
    </span>
    <span class='message secondary'>
      This is my secondary Message
    </span>
  </div>
</div>
```
And its corresponding CSS using our CSS variables:

```
.message {
  color: var(--main);
}

.message.secondary {
  color: var(--secondary);
}
```
Ok, with our message elements added we should have something like this:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rd6uarbofg27imovh4t8.png)

Now we are going to see the power of the CSS variables and why they are something that we should use more often.

With the use of just a simple class and some variables adjustments, we are able to change the whole look of our components and we do it as follows:
```
.green-theme {
  --main: #485922;
  --secondary: #798C35;  
}

.high-theme {
  --main: #00B2BF;
  --secondary: #FFC20D;  
}
```
With just those two simple clases, we are able to just slap them into a container element and everything inside will change automatically, cascading all its values. So if we add the `.green-theme` class to the element containing all the elements, in our case the element with class `.theme` we should see something like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xfg1acoyhhkxjguqhdsj.png)

*Note: We actually don't need the class `.theme` for all of this to work, we could just use the `.green-theme` class and everything should work exactly the same*

And if we use our `.high-theme` class we should see something like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hd8o4z1o3z9te5c9bwq4.png)

From this point we could continue creating more components/elements that make use of our variables, add more variables and create more stuff, and just by changing the values of our variables inside the `.green-theme` and `.high-theme` classes, all the values magically adapt.

If we wanted to do something like this using only SCSS variables, it would be a much longer process, since our SCSS variables won't cascade the same as our native CSS variables.

In this [pen](https://codepen.io/chekoMC/pen/KKaveQm) you can see both options and check how the SCSS code won't work if we follow the exact same as native CSS variables.

What do you think now about CSS variables? Remember that we can use both SCSS variables and native CSS variables in tandem to create amazing stuff, so if we wanted to do that we could have something like this, using both at the same time ([pen] (https://codepen.io/chekoMC/pen/VwPrPzZ)):

```
:root {
  --main: #022859;
  --secondary: #024873;
  --button-text: #FFF;
}

$main: var(--main);
$secondary: var(--secondary);
$button-text: var(--button-text);

.green-theme {
  --main: #485922;
  --secondary: #798C35;  
}

.high-theme {
  --main: #00B2BF;
  --secondary: #FFC20D;  
}

.button {
  padding: .5em 1em;
  border-radius: .5em;
  display:inline-block;
  background-color: $main;
  color: $button-text;
  margin-bottom: .5em;
  &.secondary {
    background-color: $secondary;  
  }
}

.message {
  color: $main;
  &.secondary {
    color: $secondary;
  }
}
```

As you can see and if you've been curious enough, you'll see that this is really similar and pretty much what bootstrap or other CSS frameworks do, just in a small scale.

I hope you liked this small post and if you find a good use for this in your next project, that will be sweet!