In Build a Responsive Navbar with Tailwind, we built a navbar that we'll use to start out this lesson and drop our account info button and dropdown.
We'll see that adding the dropdown to the navbar won't just work - the positioning is a little off and the navbar is expanding to contain the dropdown as well. We'll see how absolute
positioning solves this issue for us when we anchor it's position to the button it's associated with (by making that button a "positioned" element with relative
)
Adam Wathan: [00:00] I've gone ahead and brought back our navbar here. Now, let's try and drop our AccountDropdown into the top-right corner here and see what happens.
[00:10] I've got the navbar here, AccountDropdown open over here. First thing I need to do, a view-specific thing, but I do need to import the AccountDropdown components. We'll make sure that we add that here, import AccountDropdown from ./AccountDropdown.
[00:28] Then we should be able to just go to the end of this list here and add the AccountDropdown.
[00:36] OK, so things are really screwed up, of course. This is not how we want things to look. Let's talk about the reason for this.
[00:44] Right now, what's happening is the AccountDropdown is designed to take up this much space. Even though this dropdown looks like it's floating, it's not actually floating on top of the page. It's causing the navbar to grow in height to accommodate the dimensions of the actual dropdown itself.
[01:03] We need to do is figure out a way to take this dropdown element out of the flow of the actual page, so it doesn't disrupt the parent layout in the navbar. Why don't I walk you through how we can pull that off?
[01:18] The trick here is going to be to use absolute positioning to make sure that this dropdown, again, is not really considered part of the regular flow of the page. I'll show you what happens if we just go ahead and add the absolute class to this dropdown area.
[01:33] You can see that instantly, all the nav stuff goes back to exactly how it was. Of course, the dropdown is in a weird place, not where it's supposed to be.
[01:43] What's happening here is when we set this to absolute, it's taken out of the flow of the page so it doesn't affect the position of anything around it, but it still is rendered in the place that the browser wants to render it, the place that it would have been, had it not been in position absolute.
[02:00] Now, if we want this to be right aligned where the dropdown is over here on the left and the edge of it is up against the right, we can do that by adding a class like right-0that says the right bounce of this element should be positioned zero pixels from the edge.
[02:17] If we save that, you can see now the dropdown is looking a little bit better. It is right up against the edge of the viewport. Now, you might be thinking we're done here, but we have to be a little bit careful. Now, look what happens if I change the padding on this navbar.
[02:33] Up here, we have like px-4 which is controlling the space on the left and right. So I made this px-10, so we have a lot more space.
[02:42] Notice how the dropdown doesn't actually move even though the button moved. This is a sign that we've wired things up in a way where we haven't defined the correct relationships between elements.
[02:54] What's happening when you set something to a position absolute? By default, it's placing it relative to the nearest, what's called in a spec, positioned container. By default, none of these elements are considered positioned. They all have a position of static by default.
[03:14] When an absolute element encounters a statically positioned parent, it basically ignores its position and keeps looking up the tree to look for the next nearest positioned element. By default, the only positioned element in the tree is the actual body element.
[03:30] Right now, this dropdown is always being positioned relative to the entire viewport. When we say right:0we're saying zero pixels from the entire body, not zero pixels from any explicitly defined container.
[03:45] Solution to this in our case is to actually create a positioned element somewhere in the tree that's going to make this show up in the correct place. The best place to do that is going to be this div here.
[03:58] If we give this a class of relative, that's going to make the browser treated almost exactly the same way it treats statically positioned elements, except now, it counts as a position reference or a positioned anchor. It's considered a positioned element, which means any absolute position to elements inside of it are going to be positioned relative to this element.
[04:19] When we say right:0here, we're saying zero pixels from the right edge of this div. Since this div is inside of this header, when we change the horizontal padding on the header, that affects the location of this div which in turn affects the location of this one since this one is anchored to this one.
[04:38] Now, if we set this back to px-4, which it was originally, you can see everything moved together in a way that makes sense.
[04:46] One thing that's also important to understand is that here we are actually relying on the fact that by default, when you give an element position absolute, the browser renders it exactly where it would have been without position absolute.
[05:00] Let's say, for example, we try to give this a top-0You're going to see that it jumps all the way up to the top, right on top of this button here. The only reason there's a little gap here is because we have this mt-2 class added.
[05:14] There's actually no way to add a class that's going to get this to go to the right place. We are intentionally relying on this top auto-behavior that make sure to put it where the browser would normally render it so that we actually have it end up underneath the button the way that we want.
[05:32] The alternative to this would be trying to figure out what's the exact height of this button, and setting a top equal to that exact amount, which to me is a little bit too magic number-ish, too much weird stuff.
[05:43] In this case, it's a lot better to rely on this magic browser behavior that just happens to put it in the right spot, so that if the height of this button was to ever change...Say, we're to set this like h-12 w-12, the dropdown is always going to stay underneath it, because it's rendering exactly where the browser would render it if we didn't have position absolute.
[06:03] By setting right-0we're only positioning it on the x-axis and letting the y-axis stay where it should automatically be.
[06:11] One other thing that I would like to change here, you can see that the button is really close to this messages link. Why don't we add a little bit of space there? I'm going to do that in the actual navbar. Let's go ahead and add a class here.
[06:25] Maybe we'll give this a margin left of six or something like that. Yeah, and I think that looks pretty good, gives us a little bit of space. Now, of course, this dropdown doesn't actually work like a dropdown. When we click this button, nothing happens. There's no way for it to make it disappear.
[06:39] In the next lesson, using Vue, I'll show you how to make this dropdown actually open and close when we click that button, as well as how to make it close on escape, and even close when you click the background outside of the dropdown area.