Building a Sliding CSS Menu without JavaScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
- This video is gonna be fun. We're building out a mobile menu that slides in and out when you click on the hamburger without JavaScript. (upbeat music) If you're new to "Self Teach Me" channel, my name is Amy Dutton, I'm a web designer and developer. If you're just getting into the space, sometimes it's hard to know where to start or what resources to trust. I wanna help you level up and get to where you wanna be. If this sounds interesting to you, hit the subscribe button below. Let's make it easy on ourselves and build this in CodePen. If you've never used CodePen before, it's a coding sandbox where you can play around with snippets or share coding examples. You can use CodePen as a guest, or if you wanna save your code, you'll need to sign up for an account. It's free, unless of course you want more features. The first thing I'm gonna do is hide the JavaScript panel. Remember, we're doing all of this in HTML and CSS, so we won't need any JavaScript. I'm also gonna use SCSS. If you've never used SCSS before, don't worry, it's not too much different than plain J in CSS, but I really like how it handles nesting. Plus, it's a great excuse to show you some of my favorite SCSS power features. So let's click on the gear icon at the top of the CSS panel and in the window that pops up, go to the CSS Preprocessor drop down and select SCSS. And while we're here, you probably noticed there's SCSS, spelled S-C-S-S all caps, and there's a Sass, spelled S-A-S-S. This might be a little confusing, but both of these options are actually Sass, but they use different formatting rules, Sass spelled S-A-S-S is very strict. There are no curly brackets or semi-colons. It's based entirely on indentation. SCSS, S-C-S-S looks a little more like the CSS you're used to working with. Also my preference, okay. So we're selecting SCSS with a C and clicking on the Save & Close button at the bottom. The first thing I like to do is step out my HTML, and then that gives me something to hang my styles on. Let's make this a little bit bigger so that it's easier to read. Let's start with our header tag. We can fit everything in here. Our hamburger menu, our navigation, so let's do that. And I create a div with a class of hamburger on it, and then I'm gonna add three spans, one for each line and our hamburger menu. Then I actually have some menu texts. So outside this div, I'm gonna create another span with a class of menu, put some menu text inside, okay. We can use the nav tag for our navigation, and then inside, we can use an unordered list for all of our navigation items. For now, I'm just gonna include some empty links for some basic pages of our site that we might have, home, about and contact. Okay, cool. The main I'll answer here, so let's start styling. Let's begin with some basic styles for our overall page. So I'm gonna use the body tag and let's give it a font family of sans-serif. Let's the font size so it's a little bit easier to read and let's give it some padding to move away from the edge of the page. Now let's style our hamburger. We have those three spans for each line in our hamburger. So we can turn these into black rectangles by saying hamburger span. So this is the nesting feature within SCSS. When it's rendered, it will actually look like this. With SCSS, that ends up being a little less typing because otherwise, I would have to type these out individually, okay. Moving on, let's make each of these three pixels tall, 30 pixels wide, and make the background black and give this a display of black. Let's add some spacing after each of these blocks so that we can see each line individually. Now let's get the menu text to appear on the same line as the hamburger, let's say margin right is 10 pixels, and let's flip this left, okay. Now let's style the actual navigation. And down here at the bottom, style the nav. We'll give this a background of gold. We want the width to span the entire width of the screen. So I'm gonna say width 100vw. This vw means viewport width. Now let's create some spacing around all the nav items. So I'm gonna give this some padding. We're going to give it 30 pixels on the top and bottom and 70 pixels on the left and right. Let's add some spacing between the menu trigger and the navigation itself. So I'm gonna say margin-top, 10 pixels. To get the menu positioned correctly, let's give this a position of absolute so that we can get it exactly where we want it. And on top of our content, so now, just gonna say left is zero. So this is looking pretty good, but you may have noticed that we've introduced a horizontal scroll bar. Our menu is actually going off the page. How did this happen? This is the traditional box model. We have our content surrounded by our padding, border and then margin. If your content is 500 pixels wide, your padding is 20 pixels, your border 10 pixels and your margin 50 pixels. The width is not 500 pixels, as you might expect. It's 500 plus 20 pixels of padding on the left and right, plus 10 pixels for the border on the left and right plus 50 pixels of margin on the left and the right. So the total width is 660 pixels. You can change this model slightly with the property box-sizing as border-box, and this will allow the padding to be included in the width. With that new property added when you say the width is 500 pixels, you're referring to the width of the content including the padding. So if you increase the amount of padding, it just eats into the content area. Some people will add this snippet to the top of their CSS. They'll say asterisk and this asterisk means everything, and I do mean everything, gets the box-sizing property applied to it. Personally, I don't like to do that. I would rather add it on as an add needed bait on, add it on as I need it. And I feel like that gives me a little bit more control and makes it a little easier to debug. So in our case, let's add that property to our nav. So I'm just gonna grab that property, delete this, and we can jump down here to our nav. Now our horizontal scroll bar is gone. So let's get rid of the bullets on our navigation. So I'm gonna say ul, style-type is none. And we wanna remove the default margin and padding, but we do wanna add some spacing between each of our nav items. So it's target the li, the list item, say margin-bottom, 10 pixels, and then let's style these links out. So let's say text decoration is none, and give this a color of black, awesome. We're done with our styling, sort of. Now we just need to handle our interactivity. So how do we do this? When you click on the word menu or the hamburger, we want the hamburger to turn into an X and have the yellow navigation slide and nav. Well, when you think about this, there are two different states, there's an on and off. The only other HTML element that manages two different states like that is a checkbox. So if you think about it, you have an on and an off, checked or unchecked. So let's insert a checkbox into our HTML. Here at the top, put our checkbox. I'm gonna give it a class name of trigger so that we can easily target it within our CSS. Don't worry, ultimately, we're gonna hide this, but for now, I'm gonna leave it like it is. That'll make it a little easier to style and see what's going on. Okay, so when it's unchecked, we wanna show the default state. We have our hamburger and the menu text. When it's checked, we wanna see the navigation and an X. So let's hide the navigation, we just wanna slide it left off the screen. Under our nav styles, where we say left is zero, let's change this to say negative 100 viewport width. Give that a save, okay, great. Now when our checkbox is checked. So within our CSS, we can target a check box that's been checked by using the checked pseudo selector, okay. So this will look like trigger since we put a class name of trigger on our checkbox, we can say checked and you'll notice that all these elements nest inside our head are on the same level. So I can actually collapse these and I'll make it a little bit easier to see. Our trigger is on the same level as our hamburger, our menu, and our nav, they're all siblings. So we can use that to our advantage in CSS, we can use the tilda to target any siblings and say nav do left zero. Now let's test this out. So checked, unchecked, showing, not showing, okay. Now we just need to add a little bit of animation. We're gonna use a transition property, and remember, when you're using transition, you need to add it to the main default state. If we add this to the check state, it will only animate in one direction, I'll show you. You're gonna say transition, and then we want to tell it what property we're going to transition. So we wanna use left and how much time the animation should take. Just gonna say three tenths of a second, and then how we wanna animate it. So you wanna say ease-in-out. I like to use ease-in and out because it means it'll go a little bit slower at the beginning, as it gains momentum to animate, and then it will slow down as it stops. Now, if we test this, you'll see that our navigation animates in, but it doesn't animate out. Now, if we move our transition property to our nav, it should animate in and out, perfect. Okay, perfect. I'm going to re-factor our code slightly. When I'm organizing my code, I also like to have the default state listed first. This helps with specificity because you want the override to be listed later in the document. Another thing I like to do is to keep all the styles for one element together. This makes it easier to find what you're looking for, and if you're coming to the project with fresh eyes, it makes it easier to see all in one place, what styles are affecting a specific item, okay. So I'm gonna cut this and I'd like to list it right under our nav properties, but this isn't right. (chuckles) When this renders out, it's gonna look like nav trigger checked, nav, because it's nested inside this nav element, so that's not right. In SCSS, and ampersand is a special element. And when you use it, it's like you're injecting the parent. If we replace nav with an ampersand, it will inject the parent, so our parent here is nav. So this will render out as trigger checked nav, just like we want. Now we need to animate our hamburger to an X. To make this easy, I'm gonna style the default state, and then we'll refactor to use our check state, just like we did with our navigation. We can target the first line in our hamburger with another pseudo selector called first-child. So here we have our hamburger, we have our span. And I'm gonna say ampersand first child. So we're using that ampersand again. And this inserts the parent element. So it'll render out as hamburger, span first-child, okay. Now we want to rotate the top line 45 degrees, transform, rotate 45 degrees, and then we wanna move it down eight pixels from the top, and we wanna move it relative to where it is right now. So we can do that by adding a position of relative. And we can target the last line with a similar pseudo selector, so this one's called last child. This time, we wanna rotate 45 degrees in the opposite direction. So we can say negative 45 degrees. This time, we wanna move the line up instead of down. So I'm gonna say top, negative eight pixels. And then again, in order to move the line relative to where it is right now, we also need to add a position of relative. So you may have noticed there's a little bit of redundancy, we're saying position relative for both the first-child and last-child. So we can make this a little bit cleaner by moving the position relative up to apply to all spans. Then we can delete it from this one, okay. The second line, we just want to disappear. So we can target that through the nth-child pseudo selector. And the nth-child is kind of a weird property. In the parentheses here, you pass in a formula for which elements you want to select. So you could say every third item, first five, last four, in our case, we just wanna select the second item. So we'll pass it a two and we wanna set the opacity to zero, okay, great. Now we have our X, we just need to set up the trigger. So this is gonna be similar to our nav. In fact, we can just copy the trigger checked selector and paste it in front of the items that we just created. Now, when we click on our checkbox, you should see it snap to an X, and then back into a hamburger. To animate between the two states is really easy, we can use the transition property again. Remember, this goes on the main span and we're animating three different properties, top, opacity and transform. Technically we could say all, but when you use all, the browser has to watch all the properties. So it's far more performant if we list all the properties out that we're animating. So I'm gonna say transform, and then I'm just gonna copy this and put a comma in between each of these items. Speed, the last piece is we need to hide our checkbox. If the checkbox is hidden, how do we trigger it as checked and unchecked? Well, let's think about a traditional use case for a checkbox. When you're using a form, you don't always have to click exactly on the checkbox itself in order to toggle it on or off, you can click the text next to it. But that only works if you have the text wrapped in a label and it's linked to the check box, but we can actually use the same marker for our purposes. So let's wrap everything inside that header tag with a label tag. So I'm gonna say label, and then at the bottom, let's close our label. Let's give this a for attribute so that we can say specifically what the label is related to. So this should point to the ID of the item that we are referencing. So we also need to add an ID to our checkbox, okay. Now can test this out by clicking on the hamburger or on the word menu, and you should see the checkbox check and the animation play, okay. Now let's hop over to our styles and hide that checkbox. Say trigger, display none. Let's do one more thing, on the hamburger styles, let's add a cursor property. That way, when the user hovers over the hamburger, the cursor will change to a pointer finger, and this will serve as a visual cue that you can click on the hamburger. Then let's do the same thing for our menu text. So down here, let's see menu. (upbeat music) I've posted all the code on CodePen, I'll include a link in the description below. Feel free to download it, fork it, copy it, whatever, it's yours. If you like this video, and wanna see more videos on web design and development, be sure to hit the subscribe button below, hit the bell icon to get those notifications when new videos are posted. Until then, keep coding. (upbeat music) - I go down here, and then it shows a word, click. The guy chopped the clothy shop.
Info
Channel: Self Teach Me
Views: 757
Rating: undefined out of 5
Keywords: css menu, css sliding menu, sliding side menu css, css tutorial, css tutorial for beginners, responsive menu, css, html, sliding menu no javascript, sliding menu css, css slide animation, css side menu, css animated side menu, toggle menu html css, toggle menu, toggle menu css, hamburger navbar, hamburger navbar css, hamburger navbar html css, hamburger navigation, hamburger navigation css, hamburger navigation html css
Id: x_VYl7zz1XY
Channel Id: undefined
Length: 16min 16sec (976 seconds)
Published: Mon Oct 19 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.