Changing site’s theme using Javascript and CSS Variables

NISARG SHAH
5 min readFeb 18, 2018

I’ve discussed in past about what CSS variables are, how to use them and how to change their values using Javascript. In this post I intend to show how you could allow the site visitors to change the site’s theme using CSS variables and Javascript.

Before we begin, let’s look at what we intend to achieve. Our page is quite simple to begin with. It has a header (containing a logo), a left navigation bar, a main content area and a footer. It uses orange as the primary color, and white to complement it. You can see the full markup on my Github repo.

We want to provide a set of theme buttons to the user, such that, as the user clicks on these buttons, the theme colors on the page are swapped using Javascript — without reloading the page or fetching additional CSS. Here’s how the end product should look like:

Step 1: Declare the primary colors

Originally you might have declared the primary color in hundred different rules in the stylesheet. These rules might even be spread across multiple CSS files used by different pages.

So, the first step would be to declare the primary colors into a :root declaration and replace the hardcoded “green” references with a call to the value of CSS variable.

So, initially your stylesheets might look like:

.logo {
color: white;
background-color: green;
}

Instead you want to declare a :root element rule, and replace “green” with var(--primary-color)and “white” with var(--secondary-color).

:root {
--primary-color: green;
--secondary-color: white;
}
.logo {
color: var(--secondary-color);
background-color: var(--primary-color);
}

This might look a bit verbose, but now your code is easier to manage. If, for example, you wish to change the primary color to “red” during a festival, you would simply need to change it in one place — i.e. :root declaration. Or, in our example, you can change it in browser using Javascript, and the change will be reflected across the entire application.

Note: You could quickly check if this works by pasting the following snippet into the browser console. It tries to change the value of --primary-color to “orange”.

document.body.style.setProperty("--primary-color", "orange");

Step 2: Create the theme selection interface

Now that you have the ability to change the theme from Javascript, you can think about the User Interface for choosing the theme. In my case, I’ve chosen to create small buttons showing the primary and secondary colors, but you could go with a variety of options, such as having a drop-down control, radio buttons, etc.

Let’s review how these buttons work. Starting with the CSS:

.theme-button {
/* Create a square. */
height: 30px;
width: 30px;

/* Add a bit of spacing. */
margin: 10px 5px 0 0;
/* Top border shows the primary color, while the bottom border shows secondary color. */
border-top: 15px solid var(--theme-primary);
border-bottom: 15px solid var(--theme-secondary);

/* We don’t want to show the left and right borders. */
border-right: 0;
border-left: 0;

/* And, remove the space between the top and bottom border. */
padding: 0;
/* Give a small box-shadow to create a border-like appearance around the buttons. */
box-shadow: 0 0 3px gray;
}

Notice that I have set the color of border-top to var(--theme-primary). This allows me to provide an inline value of variable --theme-primary to each button and that will be rendered on the top border of the button. Similar applies to the bottom border.

So, here’s the markup for a button that has orange top-border and white bottom-border.

<button type="button" class="theme-button"
style="--theme-primary:orange; --theme-secondary:white;">
</button>

Similarly, here’s how a button with yellow top-border and black bottom-border would look like.

<button type="button" class="theme-button"
style="--theme-primary:yellow; --theme-secondary:black;">
</button>

This is all we need to create a bunch of buttons representing different themes. You can see more examples of such buttons in a CodePen here.

Step 3: Javascript to change theme colors on user interaction

After setting up the markup and CSS to use the theme colors defined in CSS variables, all you need now is some Javascript that would apply the selected values of theme colors to the page.

I have chosen to go with jQuery, simply because the syntax is quite concise with it. But you could certainly use plain Javascript for the purpose.

Here’s how my code listens for click events on the theme buttons and changes the theme colors on body element:

// Listen to click events on all "theme-button" buttons.
$(".theme-button").on("click", function() {
// Read the theme colors represented by the button from its inline style declaration.
var primaryColor = $(this).css("--theme-primary");
var secondaryColor = $(this).css("--theme-secondary");
// Set the values of theme colors on "body" element.
$(document.body).css("--primary-color", primaryColor);
$(document.body).css("--secondary-color", secondaryColor);
});

That’s it! As the user clicks on various buttons, Javascript will read values of --theme-primary and --theme-secondary from its inline styles, and set those values to --primary-color and --secondary-color respectively.

You can refer to the complete page on my Github repo or see it in action on CodePen here.

You could take this to the next level by allowing users to record their favorite theme in localStorage and automatically set that theme as they open your website. Or, you could persist the preference in a database and apply the style changes as the user logs in. Whichever you prefer!

Disclaimer: I’ve kept things quite simple in the example, just for the purposes of the demo. For instance, in real world, you’d not have one primary color, but the primary color and a set of shades you’d use along with it. All I intend to demonstrate through the demo is that it is much simpler to allow users to switch themes using CSS variables as compared to conventional methods (such as swapping entire CSS files).

--

--