Toggle Navar Menu Links in Tailwind with Vue

Adam Wathan
InstructorAdam Wathan
Share this video with your friends

Social Share Links

Send Tweet

Now that we have the navbar set up in a static fashion, we want to make the button that was added to drop down into a menu on click.

We'll start by adding the markup and then style that. The mark up will need to be refactored a bit so that flexbox is only affecting the navbar and not the menu that is generated. After the refactor, we'll color and size the menu with Tailwind Utility classes.

Finally, to get the menu to show and hide on click, we'll add a Vue @click directive that will toggle component state which in turn controls Tailwind classes that control whether the menu is hidden or shown.

Adam Wathan: [0:00] Again, next, I'm going to add the link drawer that should appear underneath navbar when you click the menu button to open it up. It's the same approach as we took before. The first thing we should do is add a bunch of the markup and then style it after the fact.

[0:14] After this div where the button is, I'm going to add a new div that can hold all these links, and then I'm going to drop in a few links.

[0:21] We'll make them go nowhere for now, we're just going to make up some places they could go.

[0:26] Since this is workcation like a site where you can list properties that people can take workcations out or rent properties to go to for a workcation, maybe we have some categories like "list your property" or maybe something like "trips" for the trips that you've booked, or maybe like "messages" for talking with the host -- kind of like Airbnb-ish.

[0:48] Let's just save this and see what we get and figure out what we have to do next.

[0:51] We can see things jumped around a little bit. You can't quite say but if you look, actually we do have a couple of links hiding here on the right. Obviously, we want these links to appear below, so let's figure out the best way to do that.

[1:04] I think the easiest approach should be to just add an extra wrapper div around this content so we can make this the flex container and have this div appear underneath.

[1:13] What I'm going to do is I'm going to duplicate this header and I'm going to duplicate the closing tag as well. I'm going to move the closing tag up here since we wanted to wrap this content. We've sort of outdone the stuff.

[1:26] Instead of making this one a header, we'll make this a div, and then we'll move around a few of these classes.

[1:32] The header shouldn't be flex anymore, so let's get rid of the stuff. I think the padding should also live on this element, since this is the one at the top that has the logo and the buttons, so get rid of that.

[1:44] But the background color, we'll keep here, because I think I want to use the background color for the entire thing. That means we can get rid of the background color here, and with any luck, this should look a little bit better.

[1:54] Now, we actually have the links below, kind of hard to see. Even if we highlight them, you can't see it. But we want these to probably be like stacked on top of each other.

[2:03] What I'm going to do is I'm going to make each one of these links display block instead of display inline like they're by default. That will cause them to stack. I'm going to use the multiple cursors here so we can add some classes to these links all at once.

[2:17] Let's go with display blocks within stack. I think we probably want the text to be a little easier to read than being the same color as the background color. I'm going to go ahead and make the text white for these links as well. I think maybe we'll use a slightly fatter font like a higher font-weight.

[2:33] Why don't we go with maybe font-semibold? Yeah, I think that actually looks nice.

[2:39] The spacing is a little bit off, so let's figure that out. We don't want these going all the way to the left edge. We probably want it to feel more like the same padding that we have for the top part of the navbar.

[2:50] Why don't we start by just adding some padding to this container? Why don't we do px-4 to match the padding that we had up here? That looks a little bit better, but I think we also need some vertical padding.

[3:02] Why don't we try just doing something like py-3, just like we had on the navbar at the top? See what that looks like.

[3:11] This actually doesn't look too bad at the bottom, but we do have a lot more padding than necessary at the top.

[3:17] Why don't we split this up? Maybe we'll do pt-2 and pb-3, see what that looks like.

[3:24] Actually, you know what, let's have a little bit more bottom padding. Let's go with pb-4 at the bottom. Now we have the same amount on the left as we do at the bottom.

[3:31] I think this looks OK. Things still look a little bit tight, though. I think that's actually the space between each one of these links that I don't really love.

[3:39] Before we get into fine-tuning the space between each one, I want to think through what our hover state is going to be, because that might affect what we do here. Right now, you can see you just get the cursor, but no visual indicator in the UI itself that these are actually links.

[3:55] A treatment that I kind of like is to do like a background color so maybe when you hover it, you get like a soft gray background. It just kind of looks hovered. Why don't we try adding that and see what it looks like?

[4:08] Maybe for each one of these, we'll do something like hover:bg-gray-800. Since we're using 900 for the main background, 800 is the next step up. This is as subtle as we can go.

[4:19] In general, this actually looks pretty good. I don't like the square corners, though. Why don't we add rounded corners on hover? We can just add rounded corners all the time since they're non-visible except when you're on hover. That looks a little bit better.

[4:33] I don't love how the text goes all the way to the left edge. I think we should add some horizontal padding to each one of these links.

[4:41] Why don't we try something like px-2 and see what that looks like? That actually looks pretty good for the links themselves, but I don't like how the text doesn't line up with this left edge anymore.

[4:52] Why don't we subtract the padding that we added to each link from the container? Instead of doing px-4, we'll do px-2 here so that this two plus this two equals the four above. That's actually starting to look a little bit better.

[5:07] We could probably add a little bit of vertical padding too, maybe just like the minimum amount, like py-1, see what that looks like. Yeah. This is starting to look a little bit better.

[5:18] Right now, these are stacked directly on top of each other. You can see there's no space between the links as I move my mouse cursor up and down. This is a judgment call. You could go either way in terms of having a tiny bit of space or just having them stacked right on top of each other.

[5:31] I like the idea of having a little bit of space. I'm going to add mt-1 here. Now you can see we got a little bit of space between each one, which is nice. We got quite a lot of room to breathe here.

[5:44] We don't actually need the margin top on the first one since there's nothing to push it away from. Let's remove that. I think what we have here looks pretty nice.

[5:53] Final step is to get this drawer opening and closing when we hit this button. This isn't really a Tailwind thing. We're going to do this in Vue.js, but I think it's useful to see how we're going to do that and what Tailwind classes we're going to toggle on stuff like that.

[6:08] The first thing you need to do is add a piece of state to our Vue component here called isOpen. We'll set that to false by default. This will just track whether or not the menu is open. If the menu is closed, then we actually don't want to show this section.

[6:24] Let's add a conditional class here using Vue. We'll say if isOpen is true, then we want to display block, which is the default for div so that's visible. Otherwise, we want to use hidden and set it to display none.

[6:40] You can see that by default it's hidden. If we toggle this to true, it should refresh and be open.

[6:46] Next, let's make the actual button trigger this toggling. Really easy to do. I'm just going to add an @click here. I'm just going to say whenever someone clicks this button, isOpen should become the opposite of whatever it already is.

[7:00] Now if we go ahead and click this button, we should see that, yeah, it works.

[7:03] One tiny change that we could make right now, this hamburger icon stays as a hamburger icon even when it's open. I think it'd be nice if it changed to an X when it's open. I have another SVG icon for an X in the clipboard that I'm just going to paste in here.

[7:20] What I've actually done is I've just copied the path, because the actual SVG wrapper element had the same view box. We're going to use the same size and the same color and stuff, because you don't want things to jump around.

[7:31] Because SVG is just HTML, we can actually just swap it with the path inside the SVG instead of swapping out the entire SVG. What we want to do is this one is the X. We want to show this one whenever the menu is closed, and we want to show this one whenever the menu is open.

[7:48] Let's just say v-if="isOpen" so if isOpen is true, then that means we want to show the X that you can close in. If isOpen is false, so if not isOpen, then we want to show the hamburger menu icon.

[8:04] Now if I go ahead and click this, you see it turns into X. When I click the X, it turns back into hamburger menu icon.

[8:11] Again, we've made this toggleable. Inside of it, we've got these links. We've got some nice hover states and stuff like that.

[8:16] In the next lesson, we're going to work on making this properly responsive so that we can show these links up in the navbar once we have room for them to fit.