DEV Community

The best light/dark mode theme toggle in JavaScript

Salma Alam-Naylor on June 20, 2023

Learn how to build The Ultimate Theme Toggle™️ for your website using JavaScript, CSS custom properties, local storage and system settings. No fram...
Collapse
 
thatafro profile image
Méhluli Hikwa

This is lovely, as a CSS wrangler I particularly love the text changing. Your implementation is simple and straightforward. Would love to implement it sometime maybe on my personal website which I am reworking into a nextJS site

Collapse
 
whitep4nth3r profile image
Salma Alam-Naylor

Thank you! Good luck, please share the results with me when you're done! ✨

Collapse
 
thatafro profile image
Méhluli Hikwa

I managed to implement a dark/light theme toggle on this small WordPress website.
Cyberthrust Website

Thread Thread
 
whitep4nth3r profile image
Salma Alam-Naylor

Nice! Make sure you follow some of the accessibility guidelines in the post to make sure screen readers understand what the toggle is for. Otherwise, works nicely!

Thread Thread
 
thatafro profile image
Méhluli Hikwa

Thank you for that observation totally overlooked it.

Collapse
 
nickytonline profile image
Nick Taylor

Pam from The Office saying Nice!

Collapse
 
roktim32 profile image
Roktim Kamal Senapoty

Great One @whitep4nth3r

Collapse
 
brittanyhurthead profile image
brittanyhurthead

Definitely saving this to use later! So cool!

Collapse
 
incrementis profile image
Akin C.

Yes, pretty cool :D!
It's very nice of Salma Alam-Naylor to provide the code in Codepen to see how things work.

Collapse
 
schemetastic profile image
Schemetastic (Rodrigo)

Currently, I'm working on a website which it has this feature, and it's wild that this is almost how I am working on this feature, if I could give an extra suggestion...

Usually we would use darker colors in light backgrounds and lighter colors in darker backgrounds to provide a good contrast. For doing this, I would recommend doing something like this:

:root{
    --golden: #F5C215; /*For darker backgrounds*/
    --yellowish-brown: #9C7B0B; /*For brighter backgrounds*/

    --main-color: var(--yellowish-brown); /*assuming default theme is light*/
}

[data-theme="light"]{
    --main-color: var(--yellowish-brown); 
}
[data-theme="dark"]{
    --main-color: var(--golden); 
}
Enter fullscreen mode Exit fullscreen mode

Now, in our components, we would use the --main-color variable instead of --golden and --yellowish-brown to color our elements. So instead of adding specific colors to the elements depending on which theme is active, they would automatically change.

Collapse
 
edenwheeler profile image
Eden Wheeler

Great post! I really enjoyed reading your insights and the way you presented your ideas was clear and engaging. Thank you for sharing your knowledge and perspective with us.

Collapse
 
whitep4nth3r profile image
Salma Alam-Naylor

Thank you so much Eden! Glad you enjoyed it ☺️

Collapse
 
pazapp profile image
PaZapp

We appreciate you developers. Makes our life enjoyable. Imagine choosing from light and dark theme wow

Collapse
 
panayiotisgeorgiou profile image
Panayiotis Georgiou

awesome 🙂

Collapse
 
jotajeff profile image
Jeferson Silva

great job, congratulations !

Collapse
 
sreecharan1306 profile image
Sree Charan Reddy M

Thank you.
Amazing article.
Helped me a lot

Collapse
 
whitep4nth3r profile image
Salma Alam-Naylor

You're welcome!

Collapse
 
georgewl profile image
George WL

I'd argue for a combination of both - use prefers-color-scheme to set the default, and then keep track of user setting

Collapse
 
whitep4nth3r profile image
Salma Alam-Naylor

But if prefers-color-scheme isn’t available for some reason, you’ll need a default anyway.

Collapse
 
georgewl profile image
George WL

Yeah, fallbacks on fallbacks, simple

Collapse
 
dmitryazaraev profile image
Dmitry Azaraev

"While this works, it’s not classed as valid HTML and I can’t find any documentation on it! Any insight on this is much appreciated. 😅"

HTML represents DOM in text form. Any attribute name is valid, as long, as it is valid HTML/XML attribute name. data- convention means literally nothing than convention and treated exactly in same way as any other name. More over: all attributes handled in same way. So you must not say about validity just based on this. At least you should point in which schema or tool is considered invalid. However this is pointless, because, everything what works in browser - is perfectly valid.

Collapse
 
whitep4nth3r profile image
Salma Alam-Naylor

The W3C markup validation service claims that color-mode on HTML is invalid.

Image description

Collapse
 
mahozad profile image
Mahdi Hosseinzadeh

Check out this ready to use toggle which supports system theme and changes with animation:
github.com/mahozad/theme-switch