How to make a website light/dark toggle with CSS & JS
HTML-код
- Опубликовано: 7 сен 2024
- A look at how to create a dark mode toggle switch using JS, which saves the person's preference in localStorage for the next time they visit.
Code from this video: codepen.io/kev...
///// Change to dark mode using a media query instead! • Dark mode with a media...
---
Come and hangout, ask questions, suggest ideas, and meet some awesome people over in The Community: / discord
I have a newsletter! www.kevinpowel...
I've been working on some courses! Find out more: www.kevinpowel...
---
My Code Editor: VS Code - code.visualstu...
How my browser refreshes when I save: • How to automatically r...
---
Support me on Patreon: / kevinpowell
I'm on some other places on the internet too!
If you'd like a behind the scenes and previews of what's coming up on my RUclips channel, make sure to follow me on Instagram and Twitter.
Instagram: / kevinpowell.co
Twitter: / kevinjpowell
Codepen: codepen.io/kev...
Github: github.com/kev...
Hi Kevin. I think you may have made a mistake here. localStorage will always convert your value to string. So when you set it as null, it will convert it to "null" instead and that will always return true. Although you did not check on it but it may not be the best practice here. You would need to use .removeItem instead if you want it to be null or undefined
I've been a professional frontend developer for years and I still learn new tricks from you in every single one of your videos! Thank you for your work!
u are not pro then
@@mirjalol49 lol ok
this channel has made me fall in love with CSS again... not so much the projects on the channel but for the use of vs code, i shunned it for years heavily favouring notepad++ s my tool of choice , now vs code is my first choice
Thank you, I finally figured out how to do my homework
Awesome. I love how you explain clearly what the code is doing. Thanks Kevin!
@Kevin Powell is the KING explainer for CSS in RUclips..!!!
Love this and going to use it. I only have one complaint, every time a page loads I get blinded by a flash of light before it applies the dark theme
I may be a little late, but this is because your script is not executed immediately. The browser starts rendering before it runs your script, and so your script doesn't have the time to set dark mode. The way you can fix this is by writing an inline script that just reads the value from localstorage and sets the theme on your website to prevent the flashbang
It's usually a good thing that scripts don't block the browser rendering as it can be very bad for UX, but in this case you actually need it. But just a tiny inline script should be enough
This one-liner should do the trick:
document.documentElement.classList.toggle("dark", localStorage.theme==="dark")
If you want to take into account the system preference as a fallback:
document.documentElement.classList.toggle("dark", localStorage.theme ? localStorage.theme==="dark" : matchMedia("(prefers-color-scheme: dark)").matches)
Thank you for the tutorial! I have used the code to do dark mode and modified it to make a switch which does visual JS functions
Hi, not sure if you'll see this but regardless, I wanted to drop a comment to say thanks for this video. I'm currently at the end stage of a university project in which I'm building a web-app and I really wanted to include dark mode as a feature to put my own spin on things. I couldn't figure out how to do it and then I found this video of yours which has been an awesome help, so I really appreciate it. Very happy to be able to have a working dark mode now that stays consistent across pages.
Didn't know that simple thing about css variables: you can change their values :'v. As always, you opened my eyes, Kevin, thanks a lot!
RUclips algorithm now scans my brain to see what's I'm thinking. I just had a thought of implementing a dark mode toggle and before even I search any kind of thing about that this came in the feed. Bruh this is too scary now!
I need this. Thanks a million times! The local storage part is great.
The code in this video has a flashing problem on page load where it quickly flashes original page colors then dark mode colors when in dark mode. Here is what I did to prevent flashing. Put some code in the head tag and some in the body tag. Make sure the class darkMode is applied to the main tag.
if (localStorage.getItem('darkMode') === null){
document.documentElement.classList.remove('darkmode');
}
if (localStorage.getItem('darkMode') === '1') {
document.documentElement.classList.add('darkmode');
}
if (localStorage.getItem('darkMode') === '0') {
document.documentElement.classList.remove('darkmode');
}
document.querySelector('#dark-mode-toggle').addEventListener('click', function() {
var darkMode = localStorage.getItem('darkMode');
if (darkMode === null){
localStorage.setItem('darkMode', '1');
document.documentElement.classList.add('darkmode');
}
if (darkMode === '1'){
localStorage.setItem('darkMode', '0');
document.documentElement.classList.remove('darkmode');
}
if (darkMode === '0'){
localStorage.setItem('darkMode', '1');
document.documentElement.classList.add('darkmode');
}
});
Hi,
I noticed the problem you said, but when I use the code you've put it just keeps the pages permanently in dark mode, are there any other differences from what you added and the original? Thanks
Your teaching technique is awesome sir 👌
Thanks a lot 😊
Thank you so much! Maybe you can make a playlist one day: "Useful scripts to avoid extra WordPress plugins." Thanks for saving me from yet another plugin...
you're legend...... YOU ARE LEGEND sir
i was struggling with this for a week now.
But thanks to you, now i can continue my project further.
THANK YOU!
I've been trying to get this working across other pages, and finally realised I just needed to put the script before the closing body tag....which is clear in this video :/ I did have it at the bottom for the first page, but didn't realise I have my script in the head section for the other pages...just fyi :D
Thank you so much this was helpful
you got a new subscriber
Great Video, as always. You should consider posting the CSS code as well, I wanted to take a look to see where the classes where getting added and removed when the JS fired. Love your content Kevin!
I forgot the link to my CodePen! codepen.io/kevinpowell/pen/EMdjOV
Using :root custom properties with the new prefers-color-scheme media query overrides makes it a cakewalk to implement robust CSS without any JS, which is absolutely crazy
That is wonderful Kevin. I've been meaning to create a process for selecting different themes for my website and I think this will help immensely with the coding.
good tutorial! Local storage is pretty cool. I used it for an "under construction" modal for my website, so visitors would only see the modal the first time they came to my site. You can do a lot of things with it.
I was having trouble getting this to work on a WordPress + Divi site. I had to wrap the script in an event listener that listens for the DOMContentLoaded event. This let me put the script in the head.
Thank you sooo sooo much for this tutorial. I had a school project on making a website and I'm so grateful I'm able to implement this feature with the help of amazing such as this one
you gave me a new idea for writting functions , thanks
Thank you so much! Subscribed! This is one of the clearest videos I've ever seen! I'll have to check out more of your videos!
Amazing video! I'm from Brazil and i watch your videos to learning programming!
Awesome, clear and useful like always Kevin. Many thanks
Thanks, this works perfectly but anytime I reload my page with darkMode enabled the page will first appear in light mode and automatically do the transition to darkMode so the user can see the light mode for a split second before it changes. anyone knows how I can fix that?
thank You Kevin, You make the world a better place...
This is what, I'm looking for.
Amazing I learned so much from this video thanks for sharing!
Great video! It would be awesome if some of those examples you made were on codepen or alike and linked in the description! :D
I forgot to add it! codepen.io/kevinpowell/pen/EMdjOV
Thank you Sir!! You don't know how this came handy.
I think that new :has() pseudo-class will make it much easier by throwing a body:has(#design-select-dark:checked) {
--background: var(--darkmode-background-color);
} and so on.
Just what I needed.
This was incredibly helpful and informative. Thanks, Kevin!
Thank you so much Kevin! This video was very helpful.
thank you for your amazing content!!!!
straight to the point plus a great way to explain
this is the best video this helped me a lot thanks and plz try to make more js videos you are a good js teacher. THANKS, A LOT
Thanks! Exactly what I needed.
Wow you simplified it sooo much. Thank you!!!
Hi, I really love your html and css videos, but I was hoping you could do a JavaScript series. I'm struggling with it a little and I need your help.
I'd just like to add that both SVGs (click here and the icon) should have aria-hidden set to true so screen readers don't get confused by it.
That's true. I should have also used an aria-label on the button as well.
Is it possible to have the media query and JS to coexist, so if a user has dark mode enabled on their OS, but prefers the color scheme of light mode, they can switch it and have it stay that way?
Well, if they had prefers dark, but used this switch, wouldn't it work? You could use prefers-color-scheme to set the default maybe?
Can you make a video to make the dark mode to all pages
Like the button is in the home page when you click it the dark mode well be on all pages
Your videos are so great! Thank you-- this helped a lot!
Is there a way to use this in combination with the media query?
Would be interesting to see a way to stop the two from conflicting (or maybe they won't - I'm fairly new to this) I just noticed your codepen of this example doesn't seem to react to the device theme.
I would simply do the media query by default and if the localstorage item exists then use its value as the theme (‘dark’/‘light’) or true/false
omg thank you for this video 🥰so helpful
Why did you declare the enableDarkMode and disableDarkMode with the const enableDarkMode = () => { }, instead of just saying "function enableDarkMode(){}"? Im new to javascript and this is kinda confusing
I basically written all of the code as you did and added it to my website and while i click the button colors are changing, but after i click another time they just stay in darkmode and after refreshing they get back to default light mode web page colors. Any ideas why could this be happening?
really helpful, big thanks for you! cheers!🍹
Please do more videos like this!
I get a flash when I change pages on my site.
Does anyone have solve this yet?
why does page flickering happens when we try localstorage and how to stop it. it happens when I try dark mode using the above code
Local storage still gives me a flash bang every time I reload the page.
Dropping a bit of code in the head to delay page load doesn’t work for me either.
Great video Kevin! Thank you for sharing!
does anyone knows how to combine the media query method and this method because i thought this video was a continuation but instead just shows another method
because i've spent time reconstructing my navbar in every pages to add that one button as a toggle i dont want to regret that :)))))
Hello Kevin, great content❤
It is worth mentioning that localStorage and also sessionStorage access should always be wrapped in try/catch blocks because sometimes it will throw an error. For example in Safaris inkognito tabs there is no storage which would crash the code
Is there any way around the flash of light mode as the javascript executes on a page refresh?
If there is, I don't know about it. Even YT which uses a media query (I think?) has a flash every time I visit it before it goes to dark mode.
@@KevinPowell I’m working on an admin UI and the user has to be logged in to access it, so I’ve decided to go directly into the code the generates html.
The user can select and save their UI preference and the appropriate class is rendered straight in the html on load.
@@KevinPowell I remember from looking at mmenu.js there was some css to stop the flash of unstyled menu as the JS loads, but it will be bad practice to use display none on the body.
So basically unless the JavaScript has added a mode-loaded class the body would be hidden
body:not( .mode-loaded) {
display: none;
}
Probably a bad idea, but would work in theory.
amazing! this was really helpful! thank you
Is it possible to change the source of an image when I turn on darkmode?
Great! Thank you! It's a best solution for my problem.
Great tutorial!
Interesting video but instead of a disable and enable function couldn't the not operator be used so you would only need a single function?
hey thanks for your video! I did something similar and works fine but I would like to leave my html file as empty as possible? Could you tell us how to transfer this in a typescript or javascript file? thanks
So I copied the code and saw that it didn't work but then i switched to css and it worked
Awesome tutorial man! Appreciate it
he explains it sooo good those
I always store darkmode in a cookie so you also have the info available on the server
12:08 your null also satisying following condition if(darkMode !== 'enabled'), just changing logic of if codition would have resolved that problem easily 🤷
You are the Goat 🐐
Thanks dude, just in the point
Thank you for the video!! 🙌
Thanks! This was really helpful. How would we make this so that this can work for multiple buttons? I'd like a separate button to do the same. But only the first button works.
You'd have to use a `querySelectorAll` instead of a querySelector, but that gives you back a node list, so you'd have to loop through that to set the event listener for each one
thx bro, u solve my problem
Doing it like this you'll get flash of incorrect theme, FOIT
Awesome video.
I can't add a class to anchor tags through JavaScript.
what about a simpler function like this:
function setDarkMode(bool) {
const fallback = document.body.classList.contains('darkmode');
darkMode = bool ?? fallback; // Web Dev Simplified got a video about this
document.body.classList.toggle('darkmode', darkMode);
}
this will even have a fallback when used without a value to just toggle the darkmode:
// toggle using fallback
setDarkMode();
// toggle using a boolean
setDarkMode(true);
this way, you can toggle using a boolean while loading the website, but ignore the input value when using the toggle button, or, you can completely forget about the input, but use a simple if statement when loading the website, like in the video
Great video, thank-you.
Thanks Kevin!
Hey Man first of all Great Video. And secondly is when I'm running this code using live server the code is not working!
What i mean is after switching it in dark mode i closed the browser and when i start it again it was still in light mode! Please Help me out ASAP!
Thank you!
This is sweet. Thanks!
6:05
when i test the button, the console gave me an error "Uncaught TypeError: darkModeToggle is null"
can anyone help please
Wow ! Kevin really cool and powerfulll
Excellent video!
God bless you kind man
Can I pass the darkmode setting through the next pages for my website?
One more question, on pages with a heavy page load - will there be a flickering? Because it can take some time before everything is rendered and the JavaScript gets executed.
It's very possible, yes.
You could use the color-scheme meta, and assuming they use the toggle to match their system preferences (which I'm guessing is most people), it should help prevent the flash. Or at least as drastic of a flash, depending on the color scheme being used).
we need video version 2022 :D
Awesome work,
But why it's not working on my Safari ... 'QuotaExceededError'
Wow, it's awesome....💙💙💙
Not too familiar with SVG. How do you generate that SVG code?
For example you can export it from such programs as Adobe Illustrator.
thanks for your video
Nice!
Really well explained video, thank you! Out of interest, does that local storage only apply to your website (ie: the one you're setting the dark mode for) or could any website use it (assuming they used the same variable name)?
Local storage only applies to the current domain, so only your website.
Super! Thanks
How to get localstorage value in asp.net code behind