Dark Mode with JavaScript and CSS

Muhammed Celep
4 min readApr 22, 2020

Instructional Guide To “Modernizing” Your Application

Gece = Night | Gunduz = Day (Language: Turkish)

Most websites have a switch that toggles between “light” and “Dark” mode, this is an unspoken rule for modern day applications. Now, I can go into a lecture about why it was created and how it’s beneficial but let’s keep this simple and light, let’s be real, this trend started because it simply just looked cooler.

Our journey starts from humble beginnings, the CSS File. What we’re going to do now is add our light or default mode css variables to the :root pseudo class. Why the root? We want to use :root because we want to avail the variables globally.

:root {
--primary-color: #302AE6;
--secondary-color: #536390;
--font-color: #424242;
--bg-color: #fff;
--heading-color: #292922;
}

What’s Yin without Yang, now for the Dark Side:

[data-theme="dark"] {
--primary-color: #9A97F3;
--secondary-color: #818cab;
--font-color: #e1e1ff;
--bg-color: #161625;
--heading-color: #818cab;
}

Congratulations, you’re a pro now, please update your LinkedIn profile before advancing to the next step! Jokes aside, what now? We have the roots set up (pun intended), how do we implement this into our code? We’re going to reference it like so:

body {
background-color: var(--bg-color);
color: var(--font-color);

/*other styles*/
.....
}

h1 {
color: var(--secondary-color);

/*other styles*/
.....
}

a {
color: var(--primary-color);

/*other styles*/
.....
}

Now, before diving even deeper, let’s navigate to the HTML File and add this component here:

<div class="theme-switch-wrapper">
<label class="theme-switch" for="checkbox">
<input type="checkbox" id="checkbox" />
<div class="slider round"></div>
</label>
<em>Enable Dark Mode!</em>
</div>

Essentially, what we have right now is but a mere checkbox. We all have our dark times, yes, but we should support our little <div>, don’t leave the page please, bear with me here, we’re almost there. Lets slap some CSS on that bad boy, navigate to your CSS File and add in:

/*Simple css to style it like a toggle switch*/
.theme-switch-wrapper {
display: flex;
align-items: center;

em {
margin-left: 10px;
font-size: 1rem;
}
}
.theme-switch {
display: inline-block;
height: 34px;
position: relative;
width: 60px;
}

.theme-switch input {
display:none;
}

.slider {
background-color: #ccc;
bottom: 0;
cursor: pointer;
left: 0;
position: absolute;
right: 0;
top: 0;
transition: .4s;
}

.slider:before {
background-color: #fff;
bottom: 4px;
content: "";
height: 26px;
left: 4px;
position: absolute;
transition: .4s;
width: 26px;
}

input:checked + .slider {
background-color: #66bb6a;
}

input:checked + .slider:before {
transform: translateX(26px);
}

.slider.round {
border-radius: 34px;
}

.slider.round:before {
border-radius: 50%;
}

Reload and Viola. Caution: you may be experiencing severe depressive disorders and reconsidering your life choices for it’s but a mere cover, a fake, a poser if you may. It doesn’t change anything at all, reality is a lie, pineapples grow in the ground, not on trees, all Froot Loops are the same flavor, and baby carrots are actually normal-sized carrots cut to a small size.

So let’s make dreams into reality with the magic of JavaScript! Please navigate to your JavaScript File and Input the code as follows:

const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');

function switchTheme(e) {
if (e.target.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
}
else {
document.documentElement.setAttribute('data-theme', 'light');
}
}

toggleSwitch.addEventListener('change', switchTheme, false);

What did we just do? We added in “Event Handlers” to handle accordingly the check/uncheck event of toggle-switch. You’ll notice the “data-theme” attribute we referenced in CSS above, this is where it's getting added to our root element, fascinating isn’t it? Next, let’s add a method to store the users preference for future visits:

function switchTheme(e) {
if (e.target.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark'); //add this
}
else {
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light'); //add this
}
}

Here, we’re using the Browsers localStorage to store the user preference, don’t mind the details under the hood. Alas, the final step. You’ve come a long way, remember how just about 3 minutes and 34.5127 seconds ago our function was just a simple checkbox? Be proud, you helped it come this far, you’re the one who raised it into the slider it is today, please don’t cry. Let’s give it one last gift, a “cherry on top” in a sense. A way to check for saved user preference, if any, on load of the website. This will be our graduation gift to our function, say your last goodbye’s because you wont ever touch it again. Once you’re ready, add in this last piece:

const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;

if (currentTheme) {
document.documentElement.setAttribute('data-theme', currentTheme);

if (currentTheme === 'dark') {
toggleSwitch.checked = true;
}
}

You did it, you deserve a reward yourself for having the patience and control to read this far through my witty comments and jokes, congratulations! Unfortunately, I do not have a cherry to put on the top of your head but I do have a virtual high five for you!

--

--