DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 966,155 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for Simple Dark/Light mode
matoval
matoval

Posted on • Updated on

Simple Dark/Light mode

Here is the simplest way I found to add dark mode to a project:
Add a toggle button in your HTML with a checkbox and an onClick calling a JavaScript function

 <label id="toggle">
   <input type="checkbox" onclick="toggleDarkMode(event)">
   <span id="slider"></span>
 </label>
Enter fullscreen mode Exit fullscreen mode

Then add a data-mode to your CSS with your CSS variables set to the dark mode colors

:root {
  font-size: 10px;
  --bg: white;
  --font-color: black;
  --btn-bg: black;
  --btn-color: white;
}

[data-mode="dark"] {
  --bg: black;
  --font-color: white;
  --btn-bg: white;
  --btn-color: black;
}
Enter fullscreen mode Exit fullscreen mode

Now all you have left is to write the JavaScript function to set or remove the data-mode

function toggleDarkMode(event) {
  const isDarkmode = event.target.checked

  if (isDarkmode) {
    document.documentElement.setAttribute('data-mode', 'dark')
  } else {
    document.documentElement.setAttribute('data-mode', '')
  }
}
Enter fullscreen mode Exit fullscreen mode

Then you can add some CSS to make the button look better and add a transition

:root {
  font-size: 10px;
  --bg: white;
  --font-color: black;
  --btn-bg: black;
  --btn-color: white;
}

[data-mode="dark"] {
  --bg: black;
  --font-color: white;
  --btn-bg: white;
  --btn-color: black;
}

body {
  width: 100vw;
  font-size: 2rem;
  background-color: var(--bg);
  color: var(--font-color);
}

#toggle {
  margin-right: 2rem;
  width: 6rem;
  height: 3.4rem;
  border-radius: 3rem;
  background-color: var(--btn-bg);
}

#toggle input {
  opacity: 0;
  width: 0;
  height: 0;
}

#slider {
  position: absolute;
  z-index: 5;
  cursor: pointer;
  height: 2.5rem;
  width: 2.5rem;
  top: 1.23rem;
  right: 1.8rem;
  border-radius: 3rem;
  background-color: var(--btn-color);
  transition: ease-in .2s;
}

#slider.dark {
  right: 4.2rem;
}
Enter fullscreen mode Exit fullscreen mode

Here is the end result:

Top comments (30)

Collapse
 
drawcard profile image
Drawcard

In addition you can implement prefers-color-scheme media queries to also trigger dark mode, if this is set in user preferences: developer.mozilla.org/en-US/docs/W...

@media (prefers-color-scheme: dark) {
  --bg: black;
  --font-color: white;
  --btn-bg: white;
  --btn-color: black;
}
Collapse
 
khuongduybui profile image
Duy K. Bui

I also read somewhere that you can also hook into the ambient sensor of the laptop.

Not sure if the following was the original published source but that's where I read it.
blog.arnellebalane.com/using-the-a...

Collapse
 
matoval profile image
matoval Author

That's awesome!

Collapse
 
matoval profile image
matoval Author

Do you have a link to your code? The code I posted in the article are only the parts of the code that have to do with dark/light mode.

Collapse
 
ben profile image
Ben Halpern

This is slick. Similar to how DEV does it but this is more elegant.

Collapse
 
matoval profile image
matoval Author

Thank you for the kind words!

Collapse
 
michaeltharrington profile image
Michael Tharrington (he/him)

Love the way this dark/light mode functions.

Also, seriously cool cover image for this post. πŸ˜€

Collapse
 
matoval profile image
matoval Author

Thanks 😁!

 
matoval profile image
matoval Author

I added the codepen at the bottom of the article.

Collapse
 
alexi_be3 profile image
Alexi Taylor 🐢

But what about IE? Aren't CSS variables not supported in that unsightly browser?

Collapse
 
bayuangora profile image
Bayu Angora • Edited on

I use dark mode too. But your method is more simple and straightforward.

Collapse
 
mrxinu profile image
Steve Klassen (They/Them)

That's pretty slick.

 
matoval profile image
matoval Author

OnClick the C needs to be capitalized

Collapse
 
nathankurz91 profile image
Nathan Kurz

This is pretty awesome. So cool seeing such an easy way to implement such a highly requested feature in many applications.

 
matoval profile image
matoval Author

You have two head tags

Thread Thread
 
matoval profile image
matoval Author

I'll write this code in a codesandbox and add it to the article.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.

Visualizing Promises and Async/Await 🀯

async await

☝️ Check out this all-time classic DEV post