0:00
Basic drop-down menus like this are boring and turn users away from your site
0:04
So in this video, I'm going to show you how to create an advanced drop-down menu, which is going to engage and bring in customers
0:13
Welcome back to WebDev Simplified. My name is Kyle and my job is to simplify the web for you so you can start building
0:19
your dream project sooner. And in this video, I'm going to show you how to create these drop-down menus that have
0:23
this nice smooth animation, contain additional information inside of it, as well as things
0:27
like forms if you want. You can really put anything you want into these drop-down menus, unlike normal drop-down
0:32
menus that just contain links, which are kind of boring. And to get started, I just have this header section that you can see over here on the left
0:39
We just have a header and it has three links inside of it. One of them is just a normal a tag
0:43
It doesn't do anything when we click on it. It's just a normal link. And then these other ones are just buttons that are going to open up our drop-down menus
0:50
And then I have a basic style sheet, which just contains the styles for the header and the link, just so I don't have to type out this boilerplate code for you
0:56
Now to get started with this video, what I want to do is I want to create essentially a dummy drop-down that we can use to do our animations and all of the code for actually
1:03
rendering out the drop-down. And then from there, we're going to start to put the content in the drop-down so I can
1:07
show you how that would work. So in order to create these drop-downs, the easiest thing we can do is wrap this button
1:13
inside of a div, which we're just going to give the class of drop-down. So if I just make sure I spell this correctly, we can put drop-down here
1:19
Now we have that div and we're going to put our button inside of that div
1:23
Then inside of that div, we're going to create essentially our drop-down menu. So this is going to be another div, which we're going to give the class of drop-down menu
1:30
And this drop-down menu is where our drop-down content is going to live
1:34
For now, we're just going to put the text drop-down content in there so we can see how
1:37
our styles are going to work. So we can just save that and move over to our styles.css
1:42
So we essentially created a drop-down and this drop-down is going to be the thing that wraps everything
1:46
And the main thing I want to set on this is a position of relative, that way we can absolutely
1:50
position our drop-down menu inside of it like we have here. So I want to take our drop-down menu and for the drop-down menu, I just want to take
1:59
the position and I want to set it to absolute because we want to absolutely position this
2:02
inside of this drop-down container, which contains our link. Now for now, we just go over to here and save our page
2:09
We can kind of see we have this drop-down content, which is showing up below our information
2:13
So far, this is working mostly how we want it to, but I want to specifically position
2:17
this in the exact location I want it to be. So I want the left to always be zero
2:20
So it lines itself up on the left. That's not really going to change anything. With the top here, I want to be a hundred percent, but I also want to add some padding
2:27
essentially between this drop-down content and the link up here. Because if we just do a hundred percent, you can see it doesn't change position because
2:33
it's butted right up to the link. So instead we're going to use calc here. We're going to take a hundred percent and we're just going to add 0.25 REM onto that
2:40
And it's just going to give us a little bit of spacing below the link. If we make this larger, for example, we change it to 0.5 REM, you can see we get even more spacing
2:48
In our case, 0.25 I think looks pretty good. Now the next thing I want to do is just get basic styling to kind of give it that white
2:53
background and shadow. So we can come in here. We can say the background color, this is going to be white, and that way we get that white
3:00
background color. We can also come in and we can give it a little bit of padding. We'll say 0.75 REM just to give a bunch of space around it
3:07
And we're also going to say that the border radius is going to have a little bit of rounding
3:10
We'll say 0.25 REM. And finally, the most important thing is going to be the box shadow we applied to this
3:15
So we'll just come in here with a box shadow. We'll say zero and two pixels
3:19
So it's going to have a little bit more shadow on the bottom portion. Then we're going to have five pixels here and zero, and then we're going to say RGBA
3:25
to give us a transparent color. 0, 0, 0 is going to be black, and we're going to say 10% opacity
3:31
So now you can see we get this nice shadow and you can see it's a little bit heavier on the bottom
3:35
That's because we set the Y to two pixels right here. Now if we wanted a larger shadow, we could change this value here and that's going to
3:40
give us more shadow or less shadow. We could also make it darker or lighter by changing this opacity here
3:45
As you can see, we get a darker shadow or we're going to get a lighter shadow with a lighter value
3:49
Now the next thing I want to work on is actually making this animate in because right now it's just static on our screen
3:54
So by default, you would normally think, well, we'll just set the display to none
3:57
And then when we bring it in, we're going to change the display to block or something like that
4:01
But instead we actually want to animate this in. As you can see, we have this nice animation here
4:04
And if you have a display none, go to something like display block. You can't animate that
4:09
So instead we need to use opacity that is going to allow us to animate this. So by default, we're going to set our opacity here to zero
4:15
So it's going to be completely invisible. And if we save, you can see now it is invisible
4:19
If we come in here with a dropdown menu and we give it a class like active, for example
4:23
then we could change the opacity here to one, and that would make it visible. Now we're going to need to hook up some JavaScript to do that
4:29
So before we do that, let's just do a little bit of testing. What we can do is we can select our link and this link that is inside of a dropdown
4:35
So we'll say dropdown. We want to get the link inside of it. And then we want to get the dropdown menu that comes after that link
4:41
And we only want to do this whenever the link is focused
4:45
And if you're unfamiliar with all of these different selectors that I'm using right here, I highly recommend checking out my full CSS selector cheat sheet link down in the description below
4:53
But essentially all this is doing is saying, get the thing with a dropdown class. We want to get the direct child that is a link whenever we focus on that link
4:59
So whenever we click it, we want to select the dropdown menu that is a sibling with it
5:03
Once we do that, I'm going to change the opacity of our dropdown menu
5:08
Opacity here to one. So now if we click this, you can see it opens that menu up
5:13
And when we click away, it's going to close. But it doesn't matter how many times I click this, it always stays open
5:18
So that's just the limit of using focus here. We're going to change this out for JavaScript in a little bit, but I like having this here
5:22
so that we can test how this is going to work before we implement the JavaScript
5:26
You will notice though, there is no animation. It just appears immediately. So what we want to do is set up a transition
5:31
We can just say transition here and we can set a delay. For example, we want to have a transition that lasts 150 milliseconds and we want to
5:38
do it on the opacity property. So we only want to animate opacity and we'll say ease in out
5:44
Now when I click on this, you can see it animates itself in over 150 milliseconds and then disappears
5:49
over 150 milliseconds. You will notice that over here, we kind of drop the thing in place as opposed to just
5:54
having it appear statically. So to do that, we can just set up a simple translate
5:59
So we can say transform and we want to do a translate in the Y direction
6:04
So we'll say translate Y and we're going to set up here negative 10 pixels
6:07
So by default, it's going to be essentially higher than it should be. And if we just make sure that we spell transform correctly and we come down and we make sure
6:15
that our translate Y is set to zero in the active position, you'll notice that it starts
6:19
out up high and then it's going to translate itself down. But you'll notice that doesn't actually happen and that's because we're not animating this property
6:26
So what we need to do is just set up something else in our transition for transform and we
6:30
want this to be over 150 milliseconds with the same exact timing curve
6:34
Now you can see this drops in and slides up exactly as we want
6:38
Now one final thing that you'll notice if we change this opacity to like 0.5 for now by default is that this overlaps our link and we actually can't click our link through
6:46
this which is a bit of a problem. So to get around this issue, we can set the pointer events to none
6:51
Essentially that means don't allow any interaction at all with the mouse. And then down here, we can change pointer events to auto when it's visible
6:58
So when it's invisible, our mouse doesn't interact with it. It pretends it doesn't even exist
7:02
And then when it's visible, it just acts like normal. So now I can actually click the link even though it's behind the drop down menu
7:08
So let's just change this opacity back to zero so we get the actual animation we're looking for
7:12
That just means that when this thing is not visible on the page, it's not actually going to be interactable
7:16
Now one other thing I want to do is you'll notice that when we hover over these links, they turn black
7:20
But when I click on it and hover away, it no longer is black. I want to carry over that black coloring
7:25
So what I'm going to do over here where we have link hover, I'm just going to add in another style for our drop down
7:29
And this is going to be for any link that is a direct child. When it is focused, I just want to apply this coloring
7:35
And again, we're going to take care of this inside of JavaScript to make it so it's not only on focus
7:39
But now when I click this link, you notice it doesn't quite work. That's because I want this to be the direct child, not a sibling
7:45
So now when I click on this, you'll notice that it keeps that black color, which is exactly
7:49
what we want. So now I've done a bunch of talk about JavaScript. So let's actually implement the JavaScript to get this to work as we expect
7:55
Let's create a script.js. And up here, we're just going to make sure we linked to that script.js and make sure
8:00
that we defer this until later. And if you're unfamiliar about this defer keyword, I have a full video on it linked
8:04
in the cards and description for you. So now inside of here, I just want to set up an event listener
8:08
This is going to be a click event listener, and it's going to just be on the body or on
8:12
the document. And that's because inside of here, I'm just going to check to see what we're clicking on
8:17
So I want to say, hey, is this a dropdown button? So is it a dropdown button
8:21
And that's going to be if the target here matches a CSS selector
8:25
And instead of using actual CSS classes for our JavaScript, I like to use data attributes instead
8:31
So if you're curious why that is, I have a full blog article on it. I'll link down in the description below
8:34
But essentially, anytime we have a dropdown button, I want to give it a data attribute, which is going to be data dropdown button
8:41
And we want to make sure that we don't have those brackets around it, because that's for the selector only
8:45
And then we can just copy that to both of our dropdown buttons that we have. And then whenever we have an actual dropdown, I just want to use the data dropdown attribute
8:52
like this. Now we can actually use those selectors in our JavaScript by just saying data dropdown button
9:00
Now what we want to do essentially here is, hey, are we clicking on this button? If so, we want to toggle our dropdown
9:05
But if we're also clicking outside of our button, we want to close it. But if we're clicking inside of our dropdown, we want to keep it open
9:11
So the first check I want to do is say, hey, are we inside of a dropdown? If so, just ignore this completely
9:16
So if this thing is not a dropdown button and is inside of a dropdown, so if it has
9:21
a parent, we'll just say target.closest. This is going to give us the closest parent that matches a selector, which in our case
9:28
is data dropdown. So if this is inside of a dropdown, then what we want to do is we just want to ignore this
9:35
So if this is not equal to null, then we're just going to return. This just says, hey, completely ignore this click 100%, just return out
9:42
And that's because if we're in a dropdown, we don't want to do anything at all. Otherwise what we want to do is we want to say, hey, if we are clicking a dropdown button
9:49
then what I want to do is I want to get the dropdown we're clicking. So let's create a variable called current dropdown
9:55
And this current dropdown here is just going to be set to e.target.closest
10:01
And we want to just copy this from up here because we're just going to be getting the closest dropdown that we're inside of
10:06
So this is getting us the current dropdown. And then I want to take that current dropdown class list and I want to toggle the active class
10:13
So essentially this is going to hide or show this dropdown depending on if it's open or not
10:17
Then the very last thing I want to do is just say document.querySelectorAll
10:21
I want to get rid of all the dropdowns that aren't already open. So essentially I want to close all the other dropdowns that aren't this one
10:28
So we'll just say dataDropdown.active. So this is getting all of the open dropdowns
10:35
What I want to do is loop through each of them. So for each one of these dropdowns, I just want to close them
10:39
So we'll say if the dropdown is equal to the current dropdown, then return, do nothing
10:46
at all. Otherwise, what we want to do is we want to take our dropdown. So make sure we return here
10:50
Otherwise we take our dropdown and we're getting the class list and we're going to remove that
10:55
active class. So this bit of code closes all the dropdowns that are already open except for the one that
11:00
we just opened. If for example, we opened a dropdown. So this code right here is going to be adding the active class
11:06
So in our styles, instead of using linkFocus, we can change this to dropdown.active
11:11
Same thing down here, dropdown.active. Get rid of the focus on the link
11:15
And now when we click on this, you'll notice it opens up. I can click inside of it. It doesn't delete it, but if I click the button again, as you can see, it opens and closes it
11:23
It's going to close that. So now what I want to do is go back into my index.html here and I want to actually set
11:28
up the real content inside of here. This content we're going to give it a class of information grid because it's going to
11:33
be a grid of information, as you can see right here. And then what we want to do is we want to have essentially a bunch of divs
11:38
We want to have divs that are going to contain each section. So we have a free tutorial section, courses, blog, and other
11:44
So we can do is we can create a div and then we can create a dropdown heading inside of that
11:49
This is going to say free tutorials because this is the first section. And then below that we can have our dropdown links
11:56
And these are just going to be a bunch of anchor tags. We'll say an anchor tag here that has a class of link and the href is just going to be nothing
12:03
And we'll say all. Then we can say latest and we can say popular
12:08
And that is going to be our three links for this free tutorials section. Let's just copy this down again, paste it in here
12:15
And we're going to have a section that is going to be for courses. So we'll just put my three courses in here
12:20
We'll say JavaScript. We're going to have a CSS course and we're going to have my react course
12:26
Then we'll copy this down again because we still have a couple more sections to deal with
12:30
So copy that down and copy it down one more time for the last section. So this is going to be for our blog and the blog is just going to say all
12:37
If I can spell properly, it's going to say latest and it's going to say popular
12:43
And then finally we have an other section for all the links that just don't really make sense
12:47
So we have a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
12:49
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
12:51
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
12:53
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
13:02
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
13:06
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
13:10
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
13:14
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
13:20
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
13:22
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
13:24
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
13:26
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
13:28
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
13:30
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
13:32
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
13:34
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
13:37
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
13:39
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
13:41
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
13:44
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
13:46
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
13:48
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
13:50
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
14:00
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
14:06
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to
14:10
my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
14:12
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
14:14
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
14:16
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
14:18
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
14:21
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
14:23
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
14:25
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
14:27
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
14:30
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
14:32
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
14:34
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
14:37
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
14:39
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
14:41
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
14:43
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
14:53
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
15:05
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
15:12
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
15:19
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
15:26
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
15:31
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
15:38
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
15:45
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
15:50
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
15:55
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
16:00
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
16:05
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog
16:10
a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my
16:15
blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog, a link
16:20
to my blog, a link to my blog, a link to my blog, a link to my blog, a link to my blog