11.4 Three-column page layout - Video Tutorials & Practice Problems
Video duration:
23m
Play a video:
<v ->Our final application of Flexbox</v> is going to be to fulfill this promise here, when we say, I'm a three column page. So we're gonna transform this gallery page into a three column layout. And now, Lee, this is one of the most common kinds of layouts, but it's also one of the most difficult to do in the pre-Flexbox days, right? <v ->Yeah, it was real pain to do.</v> It just was hard. (chuckling) <v ->But it's common enough though.</v> Yeah, it's common enough though, that like, people really wanted to do it. <v ->You can find a lot of guys online that are like,</v> "How to do the holy grail of three column layouts?" <v ->Right.</v> <v ->Yeah.</v> <v ->But I mean, you run into this a lot in applications.</v> There's a lot of times where you wanna have navigation on one side, you wanna have content in the middle, and then you wanna have some sort of sub navigation or extra information on the right-- <v ->Yeah.</v> <v ->And it's just common layout,</v> and it's crazy that for so long it was difficult. <v ->Yep, but it's pretty easy now with Flexbox, right?</v> <v ->Yes, it is very.</v> <v ->Right.</v> Well, let's take a look at this diagram again, what are we gonna be aiming for in terms of this gallery? <v ->So basically what we're gonna be doing is another example</v> of what's on the top row with the flex-grow, yeah. <v ->With flex-grow one here?</v> <v ->Right.</v> <v ->So basically,</v> our central column is gonna be where the main like photo will be. <v ->Right, and the two sides are gonna be set to flex-grow,</v> but we're also gonna set a size for them using flex-basis. <v ->Okay, so like--</v> <v ->So...</v> Yeah, we're not gonna just constrain it to the content that's inside. We'll give it a little bit extra width so that at least the width stays consistent. <v ->Okay, so this will be a good example</v> of how to combine the different aspects of Flexbox in a way that isn't illustrated here, right? It's kind of a mix and match. So we're not constrained to just the particular combinations that we happen to see here. So that's really good. I mean, I guess we're kind of just putting everything together. All right, let's take a look at our code, and we're gonna start by adding an actual navigation link. You might have noticed that I've been just typing in the gallery link, but of course, in general, you don't wanna rely on your users having to do that. So let's go to our nav links here and actually put in a link to the gallery. So it's /gallery, and let's just call it Gallery. Alright, so let's go back to our application. So you can see now gallery has appeared, so you can click on it. Same place, go to the homepage, go back to the gallery. By the way, you may have noticed something cool happening here. Look at that. Our footer automatically has the gallery link. So this is the benefit of not repeating ourselves. <v ->So yes, behold wonder of includes.</v> <v ->Yeah, this is so great.</v> So by using this Jekyll include, just remind ourselves where that is. It's in Includes nav links. By making sure that we didn't repeat ourselves and put this set of navigation links in a single file and then include it in the two places where we use it. When we changed it in one place, it automatically updated in the other place. 'Cause they're both being pulled from the same file here, nav links. Right, you can look at the footer here, the nav links are here, and then in the header, that's right there. So that's a good start to that. Now we can navigate to it. And now let's start editing the actual index page for the gallery. And for three columns, like my guess is like, correct me if I'm wrong, Lee, that we're gonna want like three divs, something like that. <v ->It's shocking, but you--</v> <v ->And actually, so we want three like internal divs</v> for each of the items, right? So each column should be an, is a flex item, and then there should be an overall div for the flex container. <v ->That's exactly correct.</v> <v ->Cool, all right.</v> So let's give it the classes. Okay, so we'll give it class Gallery for the overall. And then I see that you've put in another class, Column three. <v ->Right.</v> <v ->So this is for a three column layout.</v> <v ->You're right.</v> So the idea being that there are gonna be some styles that we're gonna attach to the flex container, that aren't only for a gallery. Say you wanted to reuse this on another page-- <v ->Right.</v> <v ->You wanna make sure</v> that the stuff that's more generic, you put in a generic class-- <v ->Right.</v> <v ->That pertains to what you're doing.</v> And then-- <v ->So maybe we'll be like,</v> that's class like other thing. <v ->Yeah.</v> <v ->Right.</v> But then we would still be able to use all of the column three styles? <v ->Right, because what you don't wanna have to repeat is,</v> display flex, flex align, like all those sort of things. There's no reason to repeat that. So you just put that in column three and then that's it. <v ->Cool, all right, so that's great.</v> And then we're gonna have a class of column for each of these. So COL just for short. So each of these is a column, and then it looks like you've put an extra class that's more semantic. So this is now, we're gonna have nav on the left, content. We're sort of name spacing it here, is what this is called in programming, we're... So that it's not confused with nav in another context, this is like nav that is specifically tied to the column. Is that right? <v ->Right.</v> <v ->The idea.</v> <v ->Okay.</v> <v ->That's correct.</v> And then in the side on the right. And it looks like that's the structure, it's kind of the skeleton, and then there's just some stub content. So on the nav. This is the actual, kind of the page. Of course it doesn't really matter what we put in here. All right. Well, let's take a look at this without any styling. Yeah, not very exciting, but it's working and it verifies that we did something right. All right, so now's where we really dig into Flexbox, right? <v ->Yes.</v> <v ->All right, let's,</v> let me just move this over here in preparation for this. <v ->I mean, this is all very--</v> <v ->I'm a little intimidated by this.</v> (both chuckling) <v ->I mean, what we did right there</v> is very basic setup for this. There's nothing complicated here. The only thing is the classing. You could easily find yourself, if you just use one class for these things, making something that was difficult to reuse over and over. So now that we have this basic setup that's reusable, we can jump into the more Flexboxy Flexbox part of it. <v ->So we're gonna put this in column styles.</v> Do we have that yet? So it looks like we don't actually have a section for our column styles, which isn't surprising since we haven't set up a three column layout yet. Where should they go, Lee? I don't, it's not obvious to me. <v ->So, because this is like a reusable part of the site.</v> It's a little more global than just a page, like the homepage. To me, I would put these after the header and footer. <v ->Okay.</v> <v ->And then if later down the road</v> I was making a two column layout or something like that, I would put them in the same spot with this. <v ->Okay.</v> <v ->Yeah, exactly.</v> <v ->All right, so some column styles here.</v> And we've got col-three. So that's the overall three column container. <v ->Mhm.</v> <v ->And so what we need to do here</v> in order to activate Flexbox, is just say display flex. Right? <v ->Just that simple.</v> <v ->Okay, does that change anything?</v> My guess is no, but I'll be wrong. (chuckling) <v ->Oh no, it will.</v> It puts them side by side at that point. <v ->Yeah, so my guess was wrong.</v> <v ->Here's a quiz, class.</v> <v ->Okay.</v> <v ->Why are they all over on the left?</v> <v ->Why are they all over on the left?</v> Well, it has to do with the defaults probably. Is it 'cause flex-grow is zero? <v ->Yeah, so when flex-grow is--</v> <v ->I'm learning.</v> <v ->Zero.</v> They're the width of the content that's inside. <v ->That's good.</v> All right, no, that was like, I genuinely didn't know the answer to that. But I feel empowered that I was able to get it. Thanks for the quiz. That's great. I'm not faking here if you're wondering, like I'm not playing dumb. Like I legitimately didn't know in that moment, and I'm proud of myself for getting the right answer. <v ->There was a moment when you were first editing this</v> and you were like, "I've never used this Flex thing before. "This is great!" <v ->(chuckling) I know.</v> It was pretty exciting. I'm just like, "Wow, people should read this book. "This is really useful for like everybody not just to, "for designers, but for developers." But yeah, all right, so let's move on. Let's style each of these columns, and what was the motivation behind these rules we've got? Oh, it looks like this doesn't have any sort of flex declarations. Is that right? <v ->No.</v> We actually add other common styling to that in a little bit. We can add it right now just to make it a little better. We can change the box sizing to border box, and add a-- <v ->Okay.</v> <v ->2em padding around it so that we--</v> <v ->Do you wanna do that right now?</v> Or should we. <v ->Yeah, yeah, we can do it.</v> I mean, they all share this anyways, so. <v ->Right, and so this is the kind of thing.</v> It gives you flexibility if you have another three column layout. <v ->Or two column layout.</v> <v ->Or two column.</v> And so it's still gonna apply the rules to each column and then we're gonna use these, because there might be differences between different-- <v ->Right.</v> <v ->Multi columns.</v> <v ->So for navigation,</v> you're gonna want it to be kind of narrow and not change size. Whereas if you're doing a two column layout, you wouldn't wanna have to undo flex styles that were applied. <v ->Right, right, so let's do border box padding.</v> So padding 2em is just gonna be inside the box because of sizing border box. Oh, that looks nicer already. <v ->Yep.</v> <v ->Okay, and then presumably we're gonna style each of these,</v> right? <v ->Mhm.</v> <v ->The col-nav, col-content, and col-aside.</v> <v ->Okay.</v> And I see there's also some extra styling, there's the Tilde selector, which I've already forgotten what that does. Let's put that in. (Lee chuckling) <v ->That's--</v> <v ->I could search the book--</v> <v ->That's the generic child selector, so--</v> <v ->So that's gonna be all of the children.</v> Is that right? <v ->That's correct.</v> So-- <v ->So...</v> <v ->No, it'll be the child columns,</v> or the generic sibling selector. Sorry, sorry, I said child. <v ->Right.</v> <v ->So it'll be all of the columns that follow a column.</v> <v ->Right, so this will put a border,</v> I'm gonna do a border left. This is exactly the same thing we did with these, right? <v ->Right.</v> <v ->It's the same theory with these little vertical bars.</v> <v ->Right.</v> <v ->So actually,</v> you find that out. So I'ma search the document for that. Okay, right. So basically we're doing this thing where we put a border left on the allies here in the header, and that's what gave us these, these little vertical bars. So we're gonna do the same thing on these columns, instead of in each element, now it's the class. So we're gonna put a border left of something on, just basically to have a visual separation between these. <v ->Exactly.</v> Just to better define the different areas of content. <v ->Got it.</v> So let's do one pixel solid and then we've got, it's a black with a sort of, with an alpha set. So RGBA black is zeros. And then, so this is almost transparent, is that right? Or is it almost opaque? I'll see. Yeah, looks like it's almost transparent. So one would be... Yeah, would be opaque, good. All right, so just, look's pretty subtle. And so now that we're actually gonna start doing the Flexbox rules on the specific right classes here, col-three, col-content, col-aside. <v ->So it doesn't need to have</v> the col-three specifications for it? <v ->I said col-three?</v> I said it was col-nav. Yeah, col-nav. But yeah. So yeah, I was gonna ask you about this. Why are we putting this in here? Just for safety. <v ->Just for safety.</v> I mean, the idea being that you could have a different desire for navigation in a different size for all three of these and then the one, the style that's right above, you could just get rid of the col-three. <v ->Yeah.</v> <v ->But I was just being slightly more specific,</v> so that if we were to do a slightly different column layout, that you could change these things around. <v ->Okay.</v> So let's take a look at our diagram again. All right, it's flex-grow, flex-shrink, flex-basis. And so what's the idea on this one, that this is the navigation column, which is gonna be like the left column? <v ->Mhm.</v> And we want it to not expand. We want it to not shrink unless there's not enough room for all the content. And we want it to start at a specific size. And so the way that you achieve all of those things is by setting flex-grow to zero. <v ->Right, so flex-grow zero.</v> <v ->Flex-shrink to one</v> <v ->Right.</v> <v ->And then a basis.</v> <v ->And--</v> <v ->So--</v> <v ->15em that you picked--</v> <v ->We're gonna use 15em for this.</v> If you didn't use a basis and you just set flex-shrink to one, then it would shrink along with the browser. But since we set a basis in there, it's always gonna try and be 15ems first, and then when it runs out of space, only then will it shrink. <v ->All right, let's take a look.</v> Will this do anything? <v ->Yeah, it'll expand in size.</v> Yeah. <v ->Okay.</v> Let's do this here. <v ->And so now if you resize,</v> it'll stay that size until it runs outta space and then it gets smaller. So what we're preventing here is what we saw on the homepage where the content kind of pokes outta the flex container. So by setting it to shrink, but also setting a basis, we're keeping it the size we want from the majority of the time, but we're also preventing it from breaking. <v ->Right, so if we did this, what would be,</v> would it be one? <v ->Or auto, or...</v> <v ->Or auto, okay, so--</v> <v ->Or zero or auto, sorry.</v> <v ->Zero or auto.</v> <v ->Yeah.</v> <v ->Okay, let's try this.</v> <v ->So now it'll just...</v> Oh, sorry, that's setting it to do nothing. <v ->Okay, so then...</v> <v ->So if you said it to the default.</v> <v ->Which is auto?</v> <v ->Auto, yeah.</v> <v ->So now, oh, I see.</v> <v ->Yeah, so it's--</v> <v ->Now, it's like, now it's breaking across,</v> but whereas if we do 15em then it'll always take up at least 15em. <v ->Right.</v> <v ->Okay.</v> <v ->Well, no, not always.</v> It takes up 15, it tries. Think of it more like-- <v ->Okay, it tries--</v> <v ->It tries to take up 15em,</v> unless there's not enough room for 15em, and then it starts shrinking. <v ->Okay. (Lee chuckling)</v> So why isn't it shrinking here? I'm trying to shrink it as? <v ->I did, make it wider.</v> There you go. <v ->But, so what do you mean by shrinking?</v> <v ->Watch, as we'll make the other ones--</v> <v ->Just the size?</v> Okay, yeah. All right, let's take a look at the next one. So the next one is, what was it? It was content. Now we want this one, I'm just referring to this here. So the behavior we want is that it's gonna expand and contract. Is that right? <v ->Yep.</v> <v ->So that means, which of the flex-grow be, then?</v> It seems like it should be one. <v ->That's right.</v> <v ->Okay.</v> 'Cause that fills the space and then flex-shrink should also be one. <v ->Mhm.</v> <v ->And then the flex-basis.</v> So what determines which flex-basis makes the most sense here? <v ->I think in this case, it's gonna do the same thing.</v> <v ->What do you mean by that?</v> <v ->Well, 'cause we're setting the other ones to not grow.</v> <v ->Okay, so we're setting--</v> <v ->So this is gonna be the only one</v> that's gonna be getting space distributed. <v ->Okay.</v> <v ->So it's not gonna matter.</v> <v ->So it doesn't matter, but it can just go in?</v> <v ->Right, we can set it to zero,</v> and then that way it'll be 1, 1, 0, which we can also shorthand down to flex one. <v ->Oh, okay.</v> Oh, look at that. Okay, so yeah, this is now taking up all this space. <v ->Right.</v> <v ->And this is over on the right,</v> just because this one has expanded. <v ->Exactly.</v> So now you can see the difference in size. So the one on the left is stopping, that's about 15em, I'm guessing. <v ->Yeah.</v> <v ->But it it'll still shrink</v> when the whole page gets smaller, when there's not enough room for all the content to fit. But otherwise, it sticks to that 15em. It'll be clearer. Unfortunately, 15em is about the same size as the one on the right. So if we change the flex-basis of the right hand column, it'll be much more apparent what's going on. <v ->Okay, let's do that then.</v> And this was the aside? <v ->Yeah.</v> <v ->All right, let's see if I can guess what these are.</v> So we want this one to... I feel like it should be the same as the other side, except maybe just a different flex-basis. <v ->That is correct.</v> <v ->All right.</v> 'Cause we want it to have the same basic behavior. This middle one is expanding and contracting, but these ones are sort of more or less constant. <v ->Mhm.</v> <v ->As sort of,</v> as constant as they reasonably can be. <v ->Exactly, without breaking things.</v> <v ->Right.</v> So let's try 20em, it's, we came up with. Oh yeah, so that's bigger now. <v ->So now when you expand and contract that you can see how,</v> when it gets too small for content, they start squishing, and it starts breaking stuff. But when there's available space, the one on the right's 20em, the one on the left's 15em, and the one in the middle absorbs most of the shrinking. <v ->Right.</v> Okay, cool. Take a look at this full size one. Great. So that's three columns. That's pretty impressive. This is the kind of thing that, this was basically impossible. I mean, it was really, really hard. <v ->Well, not yet.</v> We're gonna do one last little bit that finishes it off. <v ->Okay.</v> <v ->Because if you look at it right there,</v> those three columns are only taking up the top little skinny portion of the page. <v ->Right.</v> <v ->We don't want that though.</v> We want the whole page. <v ->Oh, so this is like back to our original here, right?</v> This is this idea? <v ->Right.</v> We want it to fill the available space, because let's say we were to set a background color on the column content. <v ->Okay, so that's up here?</v> <v ->Yeah.</v> <v ->Oh no!</v> So we want it to go all the way down? <v ->Exactly.</v> <v ->Okay.</v> Well, let's keep that there for now, just to see how this works. So what we've got here, we've got a content. Is it just the content div that we care about? <v ->No, we want them all to be the same.</v> 'Cause we don't want our navigation to stretch all the way to the bottom of-- <v ->Right, we want to go all the way to...</v> It seems like we should use another Flexbox somewhere. <v ->We should.</v> <v ->So where is that going to be?</v> So this thing, this is a flex container. <v ->Right.</v> <v ->Right, so--</v> <v ->And it's inside of a Flexbox.</v> Remember. <v ->Because it's inside the body.</v> Is that right? <v ->Yeah, exactly.</v> So we've got Flexboxes and Flexboxes, but yeah-- <v ->Right.</v> <v ->We kind of want to have another flex here, so...</v> <v ->So basically we want to,</v> what's the content container? Oh, right, so if we look back at our layout, this is like the template layout. <v ->Right.</v> <v ->This was originally a flex item inside the body,</v> but now we can make this a flex container as well. <v ->Right.</v> <v ->Is that right?</v> <v ->So flex items can also be flex containers.</v> You can have multiple levels of flex going on and use the properties down, like inherit them down, so-- <v ->Okay.</v> <v ->If we make container display flex.</v> <v ->Here, oh, I see.</v> We've got the, so this is because it's a flex item and we're gonna say display flex. <v ->Mhm.</v> <v ->Will this just work?</v> Huh, but now it seems like... <v ->So--</v> <v ->What's going on with the.</v> <v ->The problem is that our column three is the parent here</v> and it's just become a flex item. So since it's a flex item, we need to set a flex property for it on column three, and make it stretch across the page. And the way to do that would be to use our shorthand and do flex one. <v ->Oh, okay.</v> So flex one is, I've already forgotten what it is. <v ->Flex one is 1, 1, 0.</v> <v ->So this flex one is 1, 1, 0.</v> Did we use, we have this here too. <v ->Do we--</v> <v ->Yeah,</v> we could actually shorten that to flex one for the column content. <v ->Oh, okay.</v> <v ->But it is the same as that.</v> <v ->Okay, so we can do flex one there.</v> And then if it's 1, 1, 0, then this is also just flex one. <v ->Mhm.</v> <v ->Okay.</v> Let's take a look. Wow! That is great. Right, and you can go here. Yeah, and I can see how this is the kind of thing. It gives us a lot of flexibility on, like a mobile device too. <v ->Yeah, so if you have an application</v> and you wanna have navigation on the left, your content in the middle, and maybe like a toolbar or something on the right, more information, you know, this layout's gold. And then like you're saying for mobile, you can unstack all of these things. So if you want to, you can put the navigation on the top, the content in the middle, so it takes up the full width and it's not getting squished anymore. And then the information at the bottom. So it's really, really flexible. <v ->Right, and that's the kind of thing that,</v> for example, there's just no way you could do with tables? <v ->No, no, not at all.</v> You'd have to do some really complicated other CSS, or you'd have to use JavaScript to like swap things in and out, and it'd be a giant pain. <v ->Yeah.</v> Okay, well see you later on in this tutorial, how to do those sort of mobile specific stylings, but Flexbox gives us the necessary flexibility, as we said, appropriately enough, to make those sorts of choices later on. We don't have to figure out everything right now, we can make this three column here in the web app and then have a different style for mobile. So before we move on, let me get rid of this background here. That was helpful, but... <v ->It's always nice to add a color background</v> so you can see things. <v ->Yeah, that's a good trick.</v> I mean, like we've seen it previously, if you don't know if it's applying or if you don't know if the CS rules are applying at all, just do something really extreme, like changing the background color and then you'll see. <v ->I do it all the time.</v> <v ->Yeah.</v> <v ->Honestly.</v> <v ->Great.</v> Okay, well, so this is a great layout and we'll put it to work in the next section.