CSS Theme Switcher by Reverse-Engineering Alligator.io

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
one of my all-time favorite development sites is alligator IO so naturally I think we should reverse engineer some of its UI like all good development sites it gives us the option to switch between a light and dark mode and it even goes a step further to give us solarized themes as well in today's video you'll learn how to build a feature like this from scratch using CSS variables and a little bit of JavaScript and it's actually a lot easier than you might think along the way you'll also learn a bunch of other cool things like how to create this triangle shape with CSS how to create a drop-down menu without JavaScript and we'll finish up the video by giving our logo this rainbow white color transition when we hover over it if you're new here like and subscribe and grab the source code for this project on fire ship IO or github let's start by taking a closer look at what we're building today we have a navbar that's based on flexbox when you click on themes it opens a drop-down and I'll show you a cool technique for keeping this drop-down open using nothing but CSS so no JavaScript is required for the dropdown itself but when you click a button inside it does use JavaScript to change the CSS variables in the page to update the theme you'll notice we have an option for light and dark mode and then an option to Solarize which gives us a variation on top of these producing a total of four different color schemes and you'll also notice that after I select a theme and then refresh the page that theme is still applied we do that by caching the users selection in the browser's local storage on top of that we'll look at how we can control shapes and CSS and I'll throw in a variety of different animation techniques as well before we get started I just want to remind you that we move pretty quickly on this channel so feel free to pause the video or slow down the playback speed and if you want to jump to a specific feature check out the timestamps in the video description in our project we have files for HTML CSS and JavaScript all of which are currently empty let's start things off in the HTML to give our website some structure hit exclamation mark tab to create the initial HTML boilerplate from there I'm using a custom font that I got from Google and I set up the style sheet by typing link : CSS and hitting tab and then I referenced our JavaScript by typing script : source and hitting tab then we'll point that to app J s and we'll make sure to use the defer attribute so the script loads after our HTML that autocomplete stuff was done with Emmet which is built into vs code if you're not already using abbreviations like this to autocomplete your HTML you definitely should be next we'll go down to the body element and give it a class of you can think of this as our default theme currently it doesn't do anything but eventually we'll add CSS variables to it that represent the light theme for the site and then we'll write some JavaScript to swap it out with different classes then inside the body we have a nav bar on the top that has a class of nav bar and we have a header element below it which is where our logo will go and then we have the main content below that which just contains some dummy text our top navigation bar contains an unordered list that'll be a flexbox container and then inside that we'll have a few list items which will be flex items inside that container and eventually we'll add a drop-down menu here as well from there we'll throw out the header which contains an image tag and points to our logo PNG file feel free to replace that image with anything you want and below that we'll use an h1 tag for the headline front-end web development fired up and then we'll use a paragraph element for a sub headline below that and then inside the main element we'll use my favorite flavor of Epsom but if you don't like this dummy text there are all kinds of different if some generators out there which you can see on lorem ipsum io now if we open up our website in the browser you can see that it's currently pretty ugly let's go ahead and jump into the CSS file to change that we can start by quickly taking care of the boring things like setting margin and padding to zero on the body and then removing the default list style for our navbar from there I'll target the a element or the links in the page and tell them to use the current color by default HTML links are an ugly blue color with an underline instead of that we'll use current color to tell our links to inherit the color from the nearest parent this can be really useful when combined with CSS variables as we'll see later from there we'll create our navbar we'll give it a height of 70 pixels a width of 100% and for right now we'll go ahead and set their colors to static values but eventually we'll come back and change these two variables then we'll set up the class that targets the unordered list element in the navbar we'll make that a Flex container align the items in the center and then we'll space them evenly across the horizontal axis and then we'll set the height to 100% so it fills the parent navbar the end result is a basic navbar that looks like this nothing too fancy but if you do want to take things further I have a video for that now our next objective is to design the header and give it that cool triangle shape at the bottom we'll start by giving it some margin and padding and aligning the text to the center that gives us a standard rectangle that looks something like this what we want to do is trim out of this rectangle so it makes that triangle shape at the bottom the tool used to do that in CSS is the clip path property you can think of this as putting a bunch of points around the element that you can move around we can use the polygon function to add as many points as we want and then each argument to this function represents a point around that header element you'll notice that each argument contains two percentages this represents where the point lives along the XY axis so in this case zero zero would be the top left corner and 100% 100% would be the bottom right corner but when you use the clip path property just open up your web site in Firefox and use the clip path tool to play around with it if you click the icon it will actually set up the points on the element and then you can drag them around and it will automatically update that property which you can then use in your code if you want that takes care of our header now we're going to build a drop down menu using only CSS first we'll go into our HTML and then inside our navbar we'll add an additional list item but this one has a has drop-down clasp on it inside that list item we'll add a link and then an additional unordered list which represents the drop down that drop down we'll have a few drop down items inside it then each individual drop down item has its own link and for each of those links will provide an ID that represents the theme that we want to switch to so in this case an ID of light dark and solar will need the IDS to grab these links when we get to the JavaScript in a few minutes our drop down menu has a position of absolute and a fixed width of 500 pixels and we'll set the opacity to 0 by default making it invisible until it's actually focused we also need to set the z-index greater than its parent element which in this case will be 2 that will make it appear on top of the main nav bar that it sits inside of we'll give it a background and a border and then we'll round out the bottom two corners by targeting them individually now the actual buttons in the drop-down are aligned horizontally so we'll set the display to flex align the items in the center then maximize the space around the items inside that row to preview it I'm going to temporarily set the opacity to 1 and now you can see underneath this theme link we have this drop down menu we can make things look a little nicer by adding a box shadow and then I'll also move the item a little bit to the left so it's more centered around the parent theme link and we can do that by translating along the x-axis and that looks a lot better but how do we open and close this drop down we need to determine when something inside the drop down is focused and then we'll change the opacity from zero to one a transition on the parent element will make the opacity fade in and out when it loses focus now remember in the HTML on that list item we gave it a class of has dropped down well use the pseudo selector focus within to detect when a link inside that drop-down has been focused when that's the case we'll set the opacity of the drop down to 1 now when we go and click on the theme link it creates focus on that link which will cause the drop down to fade in if we click outside of it it loses focus and fades out and that's how you build a clickable drop-down menu using nothing but CSS what I'm doing next is just polishing some of the drop-down items I'll have each link take up all of the available space and then I want to display a circle next to each link with the corresponding color for that theme there's a few different ways to create circles with CSS but one way is to target the before pseudo element this allows you to add an element before the link itself which in our case will just be an empty string but we'll give that empty string a border of two pixels and a border radius of 50% with an equal width and height which will give us a perfect circle then we'll refine the alignment and margins and the end result should look like this and so now that our main UI is done the question becomes how do we dynamically change the color theme using CSS and JavaScript well the first thing we should do is outline our themes will target the root element and then we'll define classes for light dark and solar the root element is where I like to define variables for static values that don't change things like colors breakpoints and so on for this demo I have seven gray colors that are ordered from lightest to darkest and then we'll throw in blue purple and yellow as well that gives us our color scheme but in real life you'll likely have many more colors than this and a cool tool that you might want to check out to generate colors automatically is colors Co now that we have the color scheme we can use them to define variables that represent different elements of the UI like our base background will be gray zero so we're creating a variable that's based on another variable and by the way if you've never heard of CSS variables before in your life make sure to check out 100 seconds of CSS variables we can also use our variables to build up more complex values like a linear gradient so our nav background will be a linear gradient that goes from left to right using the variable gray one and the variable grade three and then we'll continue doing this for other variables that we plan to use on the UI like the text and the border color for example now when it comes time to create a different theme like our dark theme we can simply use the same variable names but give them different values our dark theme will use the background of grey v instead of gray zero but the text will use grey zero to give contrast against that background so the takeaway here is that the brand colors always stay the same but the way they're used changes between the different themes but you don't necessarily have to do things that way for example in our solar theme will override the grey colors directly to give them a more yellow green shade this allows us to use our existing enlightened dark themes but override the base colors to make them appear different you just need to make sure to give your colors the same contrast ratio if we go back to our website you can see it looks exactly the same as before why is that well we haven't actually used our variables yet the next step is to go into our Styles and use the variables that we defined in our themes basically anything that had a static color before now has a variable value another cool trick is that you can animate the change between themes by setting a transition on the background and color properties and I'll make the background change a little bit faster than the text color to give it sort of a cool offset effect now after changing all the values in your Styles you should be able to go to the body and change the light class to dark and you should see the colors update automatically and if you include the solar class it should override the grayscale colors and now we're at the point where it's time to implement some JavaScript to allow the user to change the theme dynamically in our JavaScript code we first need to grab all of the elements from the Dom so we'll do that for each one based on the ID that we said in the HTML and we'll also make a reference to the body element then we need to listen to the click event on each one of these buttons and run a callback function on each click switching between light and dark mode is pretty straightforward we just need to replace the light theme with the dark theme one way to do that is to look at the class list on the body remove the light theme and then add the dark theme that'll work perfectly fine but we could do this with one line of code using class list replace and replace the light theme with the dark theme and that's the better way to go in this case because there are mutually exclusive themes and we can do the same thing for our light button but replace the darkness with light and now if we go down to the drop down menu you should be able to switch between light and dark mode now the solar theme works a little bit different because instead of being mutually exclusive it's a applied on top of either light or dark mode will use a conditional statement to see if the body element already contains the solar class and if so we'll remove it and another cool thing you can do is you can actually change the variables directly by modifying the CSS text in your JavaScript it's not essential for this demo but sometimes you might want to calculate colors directly in your JavaScript in which case you could modify the CSS text directly and as an added touch we'll change the inner text of the solarized button based on its state then we'll apply the exact opposite logic on the other side of our conditional statement if it doesn't contain the solar class then we'll go ahead and add it so now we can switch between all our themes but if the user refreshes the page they're going to lose whatever theme they selected luckily we can easily cache their selection in the browser using local storage which is a simple key value store that's built into the browser you can access it by simply calling local storage in your script and the first thing we'll want to do when our script runs is get the users existing theme and then also determine if they are using the solar theme or not if there is an existing theme saved and we'll go ahead and add that theme to the body of the document and if local storage also has a value for the solar theme then we'll go ahead and add the solar theme to the body as well and this code will run anytime the page is refreshed or any time the user visits the website in a different window or browser to app and now the question becomes how do we save these values to local storage we can do that by coin set item where the first argument is the key or theme in this case and the second argument is the value or dark and then apply that same operation to our light theme when it comes to the solar theme we can actually just remove the is solar property because when the user is not using solar we don't need that property at all and when they are using it we'll just set the property to true now when we go to the web page and select a theme and then refresh the page it should still apply that theme and you can actually go into the browser console type in local storage and it will show you the key value pairs that are saved there and if you type in local storage clear it will erase those values we've already done a lot here but I did promise you one more thing and that's this rainbow animation when I hover over the logo it's really easy to do and can work on any type of image back in our CSS we'll go ahead and set up a keyframes animation called color rotate it will animate from a filter property a cue rotate of zero degrees which is normal and then we'll cycle through every color in the color wheel by setting the hue rotate to 360 degrees and now we just need to apply this animation to our logo when we hover over it we'll set the animation property to our color rotate keyframes and a duration of one second we'll have it apply the animation in an infinite loop and then we'll set the animation direction to rotate which will rotate the color wheel from clockwise to counterclockwise and now our logo has this cool rainbow effect when we hover over it I'm gonna go ahead and wrap things up there if this video helped you please like and subscribe and let me know what project you'd like to see next in the comments thanks for watching and I will see you in the next one [Music]
Info
Channel: Fireship
Views: 152,834
Rating: undefined out of 5
Keywords: webdev, app development, lesson, tutorial, css, html, js, javascript, frontend dev, frontend tutorial, light dark mode, theme switcher, css tutorial, css theme toggle
Id: rXuHGLzSmSE
Channel Id: undefined
Length: 13min 53sec (833 seconds)
Published: Wed Mar 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.