How To Build An Advanced Light/Dark Theme Toggle

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone in this video we're gonna build out a fully animated light dark-themed swapper using mostly CSS and a little bit of JavaScript and this video is going to teach you a bunch of great concepts for some advanced CSS as well as how you can use SVG inside your CSS so let's get started now welcome back to web dev simplified my name is Kyle and my job is to simplify the web for you so you can start building your dream projects sooner so if that sounds interesting make sure you subscribe to the channel for more videos just like this one now to get started I have a completely blank Visual Studio code project open and on the right I have the final version of our project and as you can see it's a very simple project we have a picture of a son and then a swap themes button and when we click that button that son is going to go off to the right side of our screen and the moon is going to come in from the left side of our screen and everything is going to smoothly transition to the dark theme and then when we click swap things again it's going to do that same thing moon jumps off to the right Sun comes in from the left and everything slowly transitions back to this light theme and we can click this button as many times as we want and it's going to swap between those different themes so to get started with building this let's first create an HTML file we'll call it index.html and we'll just hit exclamation point enter to generate all this boilerplate code and all this boilerplate with the exclamation point is generated using Emmet and if you want a full in-depth tutorial on Emmet I have one linked in the cards and the description down below now to get started we're gonna need our different icons for the moon this icon down here with the moon slash Sun and then finally our Sun icon and I got all of these from this website called material design icons comm so if we just search for moon here we can see here is our theme light dark and in order to get these into our CSS and our HTML because as you can see here this icon actually changes color it's swapping colors as we rotate it around so we actually need to be able to modify this inside of our CSS so what we want to do is actually grab with the SVG and if we just copy all of this code for the SVG and paste it into our HTML this is actually a code that we can modify with so we can change the color of this icon change the size of it change the scaling we can do everything we want all because we have this SVG directly inside of our HTML so let me just put a comment above this so that we know this is our swapper icon and then let's pull in our moon icon which is right here so we just want again get the SVG for that make sure we copy this come down here a little ways and we'll give this one a comment of moon make sure this is indented properly and we'll do one more this one is going to be for our Sun and if we come in here and we just search for Sun real quick it takes a little bit of time and we have our Sun icon right here so let's just click on this grab it as an SVG and we want to just copy that over so now we have all of our different icons inside of our HTML here I'm just gonna fix this spacing so that everything is perfectly spaced out as we want it and we can close that we don't need this site anymore so now that we have our different icons let's work on the HTML that goes around these icons in order to get these different styles that we want the first thing we need is we're gonna need some form of title so let's come into our body we'll just use an h2 for this and we'll call it theme swapper and let's open this up using live server so we can see what we're working with and as you can see we have themed swapper and there are three different icons down here so the next thing we need to do is create this button which is going to have the text swap themes as well as our icon so we'll create a button and inside of this button we're going to have that icon for this swapper so let's just copy this SVG and paste it into here again fix this indentation issue and there we go that's fixed and also to make this easier to work with I'm just going to condense this down so that it's a little bit smaller and I can also put the text swap themes oops themes now if we look over here we have that button with the icon and our text swap themes now lastly we need some kind of container which is going to contain our Sun and our Moon because the way that we're actually going to make these rotate off the screen when we click the button is by putting both the Sun and the moon in the same container and position 110 pixels away from the top of the screen and the other one way down at the bottom of the screen so that way it'll just perfectly Tate to the exact right spot that we wanted so we're gonna put them both just inside of the same container for now so let's just create a div to do that delete all these comments and we can just have a div inside of here and we're gonna put our moon which is this first icon here and we're gonna have our Sun as well again let's just fix this indentation oops and there we go and we're gonna copy this Sun in there as well just get rid of all this extra comments we don't really need them and we'll paste the Sun in there as the very first one again fix this just like that and again I'm just gonna put that comment back in there for Sun and then we can have the second one down here say moon just so we know which one is which when we need to go change them later so that's all the HTML that we're going to need so let's actually now work on adding a few classes so we can start styling these inside of our style sheets so the first thing we need to do is to link a style sheet we're just gonna come in here call it styles.css I'm just gonna shrink down this side of the browser so we can easily see the code we're working with and also the next thing that we're going to need to do is add in a class on our button so we're just gonna come in here we're gonna add a class we're gonna call it theme toggle button and on this SVG here we can actually just add a class to this and we'll call it icon so that we can actually modify the SVG and change its color as we change the buttons color next thing we're gonna do is this son we're gonna add a class here which is just going to say son and we can remove that comment same thing for the moon we'll add a class which says moon and we'll remove that comment since we now know which one is which lastly we want that container which contains both our Sun and our Moon and we're just gonna call it aptly named our Sun moon container so now we have a bunch of styling for our classes created so that's great so now we can move on to actually styling this with our CSS so let's create that Styles dot CSS file and the way that I'm going to switch between light and dark mode is by adding a class to our body so if we have a class which says dark then we should be in dark mode and if there's no class then it's going to be light mode by default so let's just get rid of that and inside of our sty we need to remember that so we're gonna have a body and we're also gonna have a body dark which is going to be for our dark mode and the way that we're going to swap between these two modes easily is by using CSS variables so we're gonna set the variables inside our body and then overwrite them in our dark mode for our dark theme which has that darker background and this vlo ish color so now with those two classes created let's first work on actually styling this sort theme swapper and button are dead center in our screen so let's go over here see what we have to work with and the first thing we're going to want to do is use display of flex with justify content in the center and align items in the center this is going to allow our content to be centered and in order to make our content show top to bottom we just want to change the Flex direction to be column now everything will be stacked on top of each other and you'll notice it's centered horizontally but we also want to Center vertically so we need to make sure we specify our height for our body which we'll use 100 VH which is going to be 100% of the screen size if we save that you notice this is in the center we have this annoying scrollbar so if we remove the margin on our body it's going to get rid of that scrollbar and everything is going to be dead center exactly like we want it now the next thing to work on is going to be the colors between our different themes so let's go over here and look at what our light theme looks like because this is going to be our default body so inside here we're gonna have a few different variables we're gonna have a variable for accent color this is going to be this orange color and this yellow color so between the different themes and this accent color for default is just orange red just the default HTML orange red color and we're also going to have a background color so let's create a background color in our case this is just white and we're also going to have a text color which in our case here is just going to be black pretty straightforward but we're also going to have a button text color so let's create that as well button text color this is what colors this icon as well as this button text and that in this case is going to be white now the last thing that we're going to have is the amount of time our animation takes as you can see here this takes one second to transfer between one state to the next state so we're going to create a transition delay variable woops transition delay and this is just going to be set to our delay which is one second in our case and you can change this hour you want to make it either a quicker or slower animation depending on your needs so now inside of our body dark let's overwrite some of these colors to make sure that the colors we want for this dark theme so the first thing we want to do is this accent color in our case this accent color is going to be D 0 D 0 whoops D 0 D 0 6 6 and that's going to be this yellowish color that you see over here next thing we're going to have is our background color and this is just going to be 3 3 3 and then lastly we're going to have that text color and this text color here is going to be white in this scenario and we also want to make sure that we set the button text color so we're gonna go in here and say button text color is going to be 3 3 3 and one thing that you'll notice is that our background color and our button text color are both the same between our body and our body dark so let's actually just set our button text color here to be equal to our background color and we can even just remove that down here that way once we change our background color our button text color is going to update to reference that background color so now let's start using these variables we can get started by saying in here our background color is going to be set to that variable selves our background color we're also going to set our color here equal to our text color so we'll save our text color and now let's look over here and you can see as before we have white and black so there's really not much difference here but if we come over and add a class of dark to our body so we just say dark here and save you can see now we're getting white text and we're getting a blackish colored background so we know that our light dark mode is working for our background as well as our color the next thing to work on is going to be this title we want to make it just so it doesn't take up quite as much room it's a little closer to our button so let's add a class to that title we'll just say title is going to be that class and instead of here we can just select that title and we're going to remove the margin so we'll say margin it's going to be set to zero and then we'll add a little bit of margin on the bottom and we'll just say 0.5 REM just to space our text out from our button just a little bit and I think that already looks a little better now the next thing to work on is going to be this accent color as well as this button text color so let's select that button which we called theme toggle button we're going to set the background color just to be equal to that accent color and if we save you can see we're immediately getting that yellowy colored button we can also change our color here to be equal to our button text color and if we say if you can now see the color of our icon as well as the color of our text here had just changed to be that button text color and if we remove dark from our title or from our body here and save you can see our button is orange with white text so we know that our theme swapping is working now the next thing to do is to actually style the rest of our button so the first thing I want to do is change our display here to be flexed and that's just so that we can justify our content in the center and align our items in the center and that way all the text inside of our button is dead centered and the swap themes lines up centered with the icon on the left hand side also we're going to change it so that our cursor here is the pointer cursor so we know that we can click on this and we're also going to change around some of our padding and border so add a little bit of a padding point 5 a.m. and 1:00 a.m. just to make it a larger button and we'll do a border radius here which is going to be 0.3 e/m also we're gonna remove that border around it because I don't really like that border look we're just gonna have a flat looking button here which I think looks pretty good and lastly we're just gonna remove the outline from it so we don't get that annoying blue looking outlined but because we remove the outline we need to make sure that we come back in and add a hover and focus state as you can see here we have a hover focus state which is going to be this enlargement of the button and even if we tab to it it's going to a margin so we need to make sure we add that into our button over here so it's obvious to the user that they're hovering it or going to it that they can click on it so to do that we're just going to use a simple transform so in our theme toggle button whenever we hover over it or for a theme toggle button whenever we focus on it what we want to do is take our transform property and we want to set a scale here to be a larger scale we'll just say 1 point 1 for example so going to be 10% bigger and now when we hover you can see our button becomes 10% bigger but it's doing so immediately we want this to happen slowly with that transition duration which we defined up here instead of our variables so in order to do that we can just set a transition property on our theme toggle button and we're going to set it to that variable which is transition delay and now you can see it's going to slowly animate in and animate back out and to make sure that our animation works properly in all different directions let's just make sure we set a default transform with a scale here of 1 that what we know for sure everything is going to scale in and out exactly as we want also this transition is going to make sure our color transitions also so that if we change our color from light to dark it's going to ease in and out of that color and we can actually see that by starting to add some JavaScript to our application so let's just create a script ojs and in our index.html let's make sure we import that script and we're gonna just say inside of here script Jas and if we make sure that this is a defer it means it's going to load after the rest of our HTML which is essentially the same as putting this at the bottom of your body I just prefer to use defer so now with that done inside of our script is we can actually work on toggling out art light and dark theme based on when we click this button and this is actually pretty straightforward we just want to do document query selector and we're gonna get that theme toggle button so we'll say theme toggle button and we want to do is add an event listener and whenever we click on it we want to run a function so we're gonna run inside of here a function and all this is going to do is get the body of the document get the classlist and we're just gonna toggle that dart class so now every time we click this button you can see our dart class is toggling on and off and as you can see this button is slowly transitioning our text color between light and dark but our background right now is really quick to change and same with our text color so in order to fix that in our Styles let's just go into our body and what we're going to do is just add in a transition oops transition and this transition is just going to be our transition delay just like that and now if we save and we swap our themes you can see all these colors really nicely fade in and out of each other which looks really good the last thing that we have left to do for this button is to just space out our text from our icon and if you remember right we created a class called icon so we can just select the icon inside of our button and add some margin on the right of 0.5 p.m. now as you can see we have a little bit of space between our icon and our text on the right which looks really good now the last thing to work on is going to be this Sun and Moon transition so it perfectly circles around our application as you can see here so let's first select the container that they're inside of this Sun Moon container and inside of here in order to easily make them rotate around like this we're just going to position this absolutely so let's come in here do a position of absolute and if we save immediately you can see they're just set in the center of our screen and what we want to do is make sure that this takes up the entire size of our screen so put at the top of 0 so that's going to start all the way at the top and the height is actually going to be something that's slightly different than the entire height of our screen or we're actually going to do is set the height to 200 V min and V min essentially what it does is a selects whatever the minimum size is in view so either our width or the height whatever it's shorter and it's going to be 200 percent of that width or height so in our case this is 200 percent of our width because our width is the smallest size and the reason we're using the min instead of the height here or VH is because we want to make sure that this transition looks good on all different screen sizes whether they're narrow or whether they're wide and this is because if we did the height this would be a very large container versus the actual width of our screen so instead of having a nice circular path it would actually have a really oblong kind of oval-shaped path and we want to have more of a circular shaped path so this is why we're going with V min here instead of V H another thing you'll immediately notice is we no longer can interact with our button very well as you can see when I can act cursor:pointer and only when we suffer in certain spots are we able to interact with it and that's because this sun-moon container is actually covering our entire screen so what we want to do is make sure we set pointer events to none and this essentially prevents the mouse from ever interacting with this sun/moon layer which means that we're always able to interact with the button underneath of it with no issues now with that out of the way you'll notice another issue and that's that we have this dreaded scrollbar again and that's because the sun/moon container is larger than our entire screen height so in order to get around this issue what we need to do is go all the way to our body and we just want to set here the stuff that is overflowing our container we want to hide it so we'll say overflow of hidden and now anything that overflows no longer shows up and our scrollbar is going since we can't actually see this content such as hidden now back here to our sun/moon container in order to make these elements rotate around our screen we're going to use the transform and we're actually going to set the rotate here to some form of variable which is going to be our rotation and we're just going to set that variable up here to be whoops rotation just like that and we're just going to default this to zero because it died default the Sun is going to be at the top now in order to get our icons in the correct position let's select both our Sun and we're gonna select our moon and we're also going to create a joint selector that selects both our Sun and our Moon because there's quite a bit of stuff we're gonna share between them for example they're both gonna be absolutely positioned and the Sun for example is going to have a top of 5 percent and the moon is going to have a bottom of 5 percent and if we save you can see our Sun is here at the top at 5 percent and our moon is actually off the screen because it's 5 percent from the bottom of this 200v mini container if we shrink our screens small enough you'll see the moon pop back up cousins out 5 percent away from double the width but most of the time our screen is gonna be wider so the moon is almost always going to be off our screen also you notice these icons are slightly offset they're not quite Center so to fix that again we're just gonna use flexbox so we're gonna change this to display flex justify the content in the center align the items in the center and if we save now we have our icon nice and centered in the screen and same thing with our moon it is also centered inside the screen and in order to make it so that this moon does not appear even if our screen size is small like this we're actually going to set the opacity to be zero and as you can see that moon has now disappeared but when we're in the dark mode so dark dot moon we want our opacity for the moon to be set to one and our Sun here is going to have an opacity of one in light mode but when is dark dot Sun what we want to do is set that opacity to be equal to zero now when we change to dark mode you can see that our moon is showing up and when we're in light mode you can see our Sun is showing up and in order to make these smoothly animate in their opacity we want to make sure we set a transition and this transition is going to be here for our transition delay so we'll say transition delay but we only want to transition for now our opacity whoops opacity just like that so this will only transition our opacity and none of the other properties of our icons now the last thing to do for these different icons is well make them slightly bigger we'll use 30 pixels in the width and the height is also going to be 30 pixels just so they are a little bit larger on the screen and we're also going to set the fill fill for an icon is essentially the same as setting the color for text it's going to set this color for our icon so we want to set our fill here to be equal to that accent color so it matches our buttons and as you can see our icon actually didn't change color so if we go over to our index.html you'll notice one thing about these paths is they have their fill value already set let's just remove this we don't want this to fill based on the current color we want to manually set our fill ourselves so if we remove that from our Sun and our Moon and save you can now see our icons have the correct color and when we swap themes you see our moon icon has the right color and our Sun icon has the right color now to make sure the transition of our colors is seamless let's make sure we add in fill to our transition so now our colors are going to smoothly transition between the accent color that is for light and the accent color for dark now we're finally on to the last step which is handling the rotation so that our Sun and Moon icon properly rotate in and out of the screen and we're just gonna handle that first the naive way and then we're going to look into the better way to handle the problem so the first thing you may think to do is just whenever our screen is dark we want to set the sun/moon container to have a rotation here which is going to be with rotation which is going to be 180 degrees and if we save and we switch our theme you can see that our Moon icon is now at the top and if we spot back our Sun icon is at the top so we're properly doing our rotation and if we actually set a transition here which is going to be for our transform oops transform and it's going to be over that transition duration and now we save you can see that is properly rotating in but when we actually go to swap themes back it's rotating the wrong direction we want to constantly be adding 180 to our degrees every time so it'll constantly rotates to the right every single time also you'll notice our Moon icon is upside down so to fix that instead of our Moon what we can do is we can just change the transform and we want to change the rotate to be 180 degrees that way our Moon is always going to be right side up at the top of the screen and it's going to be upside down at the bottom of the screen that really doesn't matter since it'll be invisible so in order to fix this issue what we're gonna do is actually set our rotation in JavaScript by adding 180 to the current rotation which means that we want to handle this degree portion inside of our CSS so we don't have to do string parsing inside of our JavaScript so let's just do a calc here where we multiply our rotation times 1 degree this is going to convert a value of for example 180 into 180 degrees for us and if we save you can see that this still works the way that it was before with the left and right so if we remove this and jump into our JavaScript we can actually get that Sun moon container so we'll just say Sun Moon container is going to be equal to document query selector of that class of Sun Moon container oops moon container just like that and now what we want to do is first get our current rotation and this is going to be from the sun/moon container we need to get the computed style so we can call this function called get computed style pass it in the element we want to get the computed style of and then we can say good property value and here we just pass in the property won't want in our case this is our rotation and this is going to come back to us as a string so we need to parse this into an integer so we can just use the parse int function and now pass it in that computed style which we just calculated and that's going to give us an integer which is our current rotation then we can set our new rotation like doing that same thing with our sun-moon container we want to get the style property and we want to call set property and in here we pass of the property which in our case visit rotation and then we're going to pass it our current rotation plus 180 so it's just going to add 180 degrees on to our current rotation make sure we spell rotation here and if we save click swap themes you see it go to the right and again go to the right and every time we click this it's just going to keep going to the right because we're constantly adding 180 degrees instead of adding and then removing so it's constantly going to be moving to the right as you can see here and that's all there is to creating this fully animated theme toggle if you enjoyed this video you can check out my other project-based videos linked over here and subscribe to the channel for more videos just like this thank you very much for watching and have a good day
Info
Channel: Web Dev Simplified
Views: 45,741
Rating: undefined out of 5
Keywords: webdevsimplified, light dark mode, theme toggle css, theme toggle js, theme toggle, theme toggle javascript, light mode javascript, light mode css, light dark mode css, light dark mode js, light dark mode javascript, dark mode css, dark mode js, dark mode javascript, light dark mode tutorial, light dark mode toggle, theme toggle css tutorial, dark mode tutorial javascript, dark mode tutorial css, dark mode with css variables, css variable theme toggle, light/dark mode, css, js
Id: RiWxhm5ZdFM
Channel Id: undefined
Length: 25min 46sec (1546 seconds)
Published: Sat Feb 22 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.