How to create a dark\light mode switch in CSS and Javascript
In this tutorial, we'll take a look at how to create a dark theme for your web project, and how to switch from a default (light) theme to a dark one with the help of CSS Custom Properties.
To achieve this result, we are going to define all our project colors using CSS custom properties; and then, when a specific data attribute (or you can use a CSS class) is added to the body element, we update all these CSS variables with their new dark-theme values.
For example, we can use the color white as the default background-color for a component, and then change it to black when a data-theme="dark" is added to the body element:
When the data-theme="dark" is applied to the <body> element, the background-color of the .component changes from white to black.
Apply this same idea to all the colors of your web project, and you have a theme switcher! What's missing is just a toggle element that adds/removes the data-theme to the body element when it's checked.
We've put together a video tutorial that explains how to create the switch and apply a dark theme to a web project based on the CodyHouse Framework. Feel free to skip the video if you prefer to read the article.
👋 First time you hear about the CodyHouse Framework?
The advantage of using the CodyHouse components is that they have already been built using CSS Variables; updating the value of the color variables (as explained in the first part of the article) will automatically update their styles with no additional changes needed.
Here's the list of the components used to create our final project:
Make sure to include the HTML of these components in the index.html and import the SCSS style as well.
☝️ Tip: to organize the SCSS files of the CodyHouse components, we suggest to add a separate 'components' folder and create, inside it, a separate SCSS file for each one of them. You can then import all these files directly in your style.scss (or inside a _components.scss file). The result will be something like this:
If you have selected components that have a Javascript file, make sure to include that one as well.
Here's the final result once all the components are in place:
We still need to:
Create a dark theme
Add a switch to the page
To create a dark theme, we can use the Colors Editor. Click on the '+' icon next to the 'Themes' label and rename the new theme 'dark'.
Select the Bg + Contrast scale, and pick a dark color for the --color-bg, and a light color for the --color-contrast-higher. The intermediate values are automatically generated by the editor. To preview the new theme, click on the [Preview theme] switch located on top of the editor.
If you click on the [View code] button (header of the editor), you'll notice the editor has created a data-theme="dark" attribute, where it updates the values of the color variables. You can do the same process manually if you prefer.
⚠️ Note: don't worry if you see the color variables defined using the defineColorHSL function (it does not affect the theme creation); we need this to combine SASS color functions with CSS Variables.
Make sure to replace the content of the custom-style/_colors.scss file with the new code generated by the Editor.
Now keep in mind that all the components have been built using the color variables. For example, in the Main Header component, we have:
.main-header {
background-color: var(--color-bg);
border-bottom: 1px solid var(--color-contrast-low);
}
.main-header__nav-label { // menu label
color: var(--color-contrast-medium);
}
.main-header__nav-link { // link within list item
color: var(--color-contrast-higher);
&[aria-current] { // style of selected link
color: var(--color-primary);
}
}
Because of that, when you apply data-theme="dark" to the body, the values of the color variables are updated, and the new theme style is automatically applied.
Although we use a gulp plugin to generate a fallback for CSS variables, themes other than the default one won't be visible in older browsers. That shouldn't be an issue because browsers that don't support CSS variables will still render the default theme (the content is accessible).
How to save theme selection using the Local Storage API? #
In this follow up article, we explain how you can use the Local Storage API to save the theme selection so that it's preserved while navigating the website.
If you have suggestions on what we could improve, get in touch! Any feedback is welcome.
Level up your CSS skills
💌 Each month we email a 1-minute CSS tutorial to 20K developers
📢 We use cookies to give you the best possible website experience. By using CodyHouse, you agree to our Privacy Policy.
✅ Project duplicated
✅ Project created
Upgrade to CodyHouse Pro
Unlimited CodyHouse projects
Unlock 155 pro components and counting
Unlock our collection of Templates
One-click project export
There was an error while trying to export your project. Please try again or contact us