DEV Community

Cover image for Theming with native CSS variables
Sergio Francisco Montoya Comparan
Sergio Francisco Montoya Comparan

Posted on • Updated on

Theming with native CSS variables

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

If everything went well, we should see something like this:
image

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>
Enter fullscreen mode Exit fullscreen mode

And its corresponding CSS using our CSS variables:

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

.message.secondary {
  color: var(--secondary);
}
Enter fullscreen mode Exit fullscreen mode

Ok, with our message elements added we should have something like this:
Alt Text

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;  
}
Enter fullscreen mode Exit fullscreen mode

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

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

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 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):

: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;
  }
}
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (0)