- 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.