Join Ray Villalobos for an in-depth discussion in this video Use Flexbox to create a layout for our header or navigation, part of Building a Responsive Single-Page Design with PostCSS.
- Using Flexbox with CSS is a great way to generate simple layouts. Now, there is a problem with using Flexbox in older browsers and that's because there was a slightly different version of the syntax for using Flexbox. Now, because we're using the Post CSS out of prefix, or plug-in, it's going to take care of handling the older syntax for us automatically and, therefore, will make things a lot easier to do. So, let's start working on the style for our header and navigation using Flexbox.
Now, first we need to take a look at the HTML so that you can understand what we're going to be working with here. So, if we take a look at this file, you can see that there is a header section and it has a class of header, and then we have two subsections underneath that, we have this nav subsection, right? And it has a class of nav and inside you can see that there is the branding, which is essentially the logo and then the navigation, and then underneath this nav we have this container that has this "Our Mission" tagline.
Now, let me show you what we're working towards. So this is the site when it's all finished and if we take a look at that section you can see it a little bit clearer. We have this head section, or the header section, and it has our navigation as well as our branding and then we have this Our Missions section. So, in a way I need to stack up these two different elements separately so that one will be at the very top of the screen and then the other one will lay at the bottom. And then in addition to that I have these two elements: the branding element, which is the logo which I want to align to the left, and then the navigation which needs to align to the right and then inside the navigation itself I have all these different list item elements and all those need to stack right next to each other.
So we're going to handle all that with Flexbox and we're going to start doing it right now. So let's take a look... And go back into our style.css file. We're going to create a new folder here in our process/css subfolder and this is going to be called modules. And inside that modules folder I want to create two files, I'm going to make a new one for our navigation and then make another one for our header.
Of course, whenever we do that we need to make sure that we call them in our style.css document. So, I need to import the header that's in the modules section and also the navigation that's in that same location. Right, so those are all imported, which means that we can start working on the header. Now, if you remember from the video on creating mixins we added this background image to our header, we need to go ahead and move that code out of here, so I'm going to take it, just cut it out, and then go into header and paste that back in here.
So, let's go ahead and save that. And now the header should come back. So, let's go ahead and add some code right here and in addition to just putting in a background image, I'm also going to set this area to display as flex, so notice there's a bunch of different options on how to display elements, the one we're interested in right now is the flex version. So let's go ahead and save that. And it's not going to look a ton different but you may notice that as soon as I did that, it's actually stacking the elements next to each other.
So, remember that there are two different pieces to our header: our navigation section, which includes this branding and our links, as well as this mission statement right here. Now, by default when you choose to display things as flex element, the sub elements underneath will appear side by side and this is what's happening right here, this is not what we want but this is sort of the default. So we need to modify how flex is displaying the elements and to do that we are going to use a rule called flex-direction.
So flex-direction is going to allow us to modify how this is going to be displayed. So, by default, we're going to get a row alignment, which means that things will be side by side, how you're seeing right now, but what we want is column, because we want these things to stack on top of one another. So, if we save that you should see this modified and it looks sort of like it did before, you've got the, sort of, navigation section with the branding and the links right here, and then you have this "Our Missions" section.
So, there is one more thing, and you're not really going to be able to tell how it affects the layout right now, but we need to set the space in between, or the justification of the content. So I'm going to add a justify-content rule and the options here determine how the content within this section is going to fit within the space available for these elements. Now because these items are pretty big you're not going to be able to see what's happening here, but what this option will do is take care of what happens when there is any extra space and how it's distributed between these elements.
Now, in the final layout you can see that what ends up happening when this page is kind of wider is that these items are at the top and this other section is at the bottom and then this space in between them gets sort of placed in between the two elements and this aligns kind of to the bottom and this one to the top and this what we're controlling right now. But you're not going to be able to see what happens right now because these items are, right now, way too big. But, the option that we need is space between, which means just add all this extra space in between these two elements, space-around works in a similar way but adds a little bit of sort of padding around the elements, as well.
Flex-start and flex-end would just sort of postion all the elements at the beginning or at the end. So the one that we need is space-between, and we'll go ahead and choose that and go ahead and save that. Now, as I mentioned, you really shouldn't see any differences right now because there isn't any extra space in between these two elements. So, now that the basics of our header are done, let's go ahead and work on the navigation which will be a little bit more complicated. So, we'll switch over to navigation.css file and we'll start working on what happens there.
So, I'm going to need to call the nav section, I gave it a nav class and I'm just going to set the navigation a little bit farther away from the top, so, I'm going to say margin-top and then do 1.75rem here, just to give it a little bit of space from the top of the screen. And, then, I need to work on the nav-elements. Alright, so, nav-elements is going to be the container for the branding as well as these links.
So, remember those are two separate elements in our index.HTML file. Inside nav we have this section called nav-elements and nav-elements has the branding as well as the nav bar. Those are two elements within that. So, these are also going to be controlled by using display: flex so they'll go side by side, let's go ahead and save that and right now you can't see the branding because it now doesn't have any sort of width or height assigned to it.
So, we're going to continue to add some stuff in here. So, inside the nav-elements we'll add branding and let's go ahead and do a max-width of 180 pixels and a width of 30% of the container. So, now the branding section that, the logo essentially, will take up a third of the width of these containers. So, we're able to see the logo again, and then this will take up the rest of the room.
So, let's go ahead and work on the navbar itself. As you'll notice that I'm doing some nesting of my CSS and that's something that's available in both Sass and pre-CSS. So, this just keeps everything organized a little bit better, it's sort of like how you work with media queries and it's very common to how you work with Sass as well. Alright, so here what I'm going to do is add a margin of 0 and padding of 0 to these, so, these are the actual lengths and then we will set these to also display as flex.
So, let's go ahead and see what happens when I do that. So, now these will appear side by side. So, I'm controlling just the navigation part and now I have managed to put them next to each other, which is great. Alright, so next I'm going to do a justify-content rule and here again, we need to determine how the alignment of these elements is going to work. Now, what I want is for these elements to be aligned to the end of my container.
So, if you remember from the finished layout, I want them to appear here to the right. Now, when they're really small you can't sort of tell, and as a matter of fact when we get to working with responsive layouts, you'll see that I want them to stack up like this. But, they just need to sort of go to the right of the amount of room. So, let's go ahead and do that. Justify-content, I want it to be flex-end here. And, you're probably not going to see any change because right now there's not enough room to see these side by side when I save this.
So, the next thing that I need to do is control what happens to the space in between these different items in the cross-axis. So, in this case the cross-axis is going to be vertical, so, if I make this window a lot smaller, eventually you should see these items wrap around and stack on top of one another, you can actually see it a little bit here. When the window appears to be too small, I want these elements to appear kind of on top of one another.
So, I'm going to use align-content, how the content will align, and modify that to be flex-start, because I don't want the spacing in between these elements when they start stacking to be equidistant, because normally what would happen is, since this logo is much bigger, then when this starts wrapping the space in between would get added kind of in between the items to fill this taller, sort of logo space.
So, by saying flex-start I want these things to align to the top, which is what's happening with this layout, otherwise this "people" would actually be a little bit farther down to try to fill the vertical space that's available to this branding section. Alright, the next thing is to actually tell Flexbox to wrap the elements if the container is sort of small so I'll do that next. That is done with a flex-wrap property and I'm going to just say wrap and that means that when the content is too small I want it to wrap like this, it doesn't do that by default which is sort of odd, but just by adding this property it gets taken care of pretty easily.
So, other than that let's go ahead and add some additional pieces of CSS here to just make things look nice. So, we'll say line-height and then we will make that 150%. And then we will go ahead and get rid of the the bullet points, list-style-type, and this will be none, and then make the width of this element, although it's taking up the rest of the room of the elements since I set the other one to be 30%, I'm going to set this one to be 70%.
Alright, so we saved that and you can see that at least the bullets are gone right now, there's not enough room to see everything that's going on, but now you can actually start to see how giving these elements a sort of different position made this section up here go to the top and this section down here go to the bottom. So, that is actually because of the code that we did here on header.css that says justify-content: space-between it just pushed the top one to the top and the bottom one to the bottom, so...
Flexbox is not really that hard, you just sort of have to play around with it and practice and see how the different parameters work. Okay, so other than that I just need to really do some additional plain-vanilla CSS, that you would do with anything. Our layout sort of code is done, so for the anchor tags I'll make the font weight bold, I could make it heavy if I wanted to here. And then the color, I'll make this the color of the background, which in this case would be white and then text-decoration will be none.
So, it won't have the underlines by default. And then I do need to add a little bit of padding because all of the elements are right next to each other. So, I'll do padding and then 0 and 1 rem, now I'm not adding any padding to the top and bottom because all that spacing is being handled by our Flexbox, so I don't really need to add any padding but I do need to add some in between the elements. So, there you go, that looks pretty good. They're stacking up kind of nicely and just so that we can visually see what happens on hover, I'll go ahead and add another rule here that just changes the color of this to yellow and I'll go ahead and save that.
And now we have a navigation that, although isn't perfect, it's most of the way there. There is still a little bit of work that we need to do on this to make everything look cool. Now, Flex really isn't that hard to work with. Since we don't have to worry about prefixes for slightly older browsers, it's actually quite fun to mess around with, I highly suggest that you play around with these different parameters and see how modifying them changed the layout. Now, if you want to learn more about Flexbox, we have an awesome course by the amazing Morten Rand Hendricksen, it's called Advanced Responsive Layouts with CSS Flexbox, so if you want to dig into the details of Flexbox I highly recommend that you watch that course.
- Structuring the HTML markup for a single-page design
- Using PreCSS Sass-like imports in PostCSS
- Creating Sass-like variables with PreCSS
- Building styles
- Creating a layout for the header and navigation with Flexbox
- Creating and styling sections
- Animating page elements with PostCSS