Creating a Two Column Layout with CSS Grid and Flexbox
Now that we have all of our content here, I think we are ready to add our square styles, and I think you'll also be pleasantly surprised by how little amount of code you're going to have to write in order to get this working.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
  • Complete the Exercise
Video locked
This video is viewable to users with a free Dev Camp account

I'm going to come down to the bottom of the common.css file and I'm going to say these are the square, let's say square grid styles. And now inside of here, let's add our styles for the squares wrapper. We'll say display flex, and justify content here is going to be center, so that is going to take the entire set of code.

So let's reference our HTML one more time. Remember squares wrapper is what is wrapping up all of the content, and then inside of it we have a single div called squares. And so this is going to take that squares div and it's going to simply align it centered along the horizontal access.

Now that we have the squares wrapper set, now we can grab that once again. And this time we're going to grab the square inside of it. Actually, sorry, squares. Don't wanna get that one wrong. Here we simply want to dictate a width, so here the width is going to be 1,000 pixels, and that's all we're going to need to do for the squares.

common.css

/* Squares grid styles */
.squares-wrapper {
    display: flex;
    justify-content: center;
}

.squares-wrapper > .squares {
    width: 1000px;
}

Inside of here, remember, we have our single square. This is going to be where we are going to build out our grid, so we have squares and then inside of that is going to be our square class. And for this I want to use CSS grid, because at the end of the day what we are building out is a grid layout. So I think it is a good fit for using CSS grid.

So I'm going to say display grid, and then inside of that I want to set up our grid template columns. Here we have grid template columns, if you remember back to the last time we used grid, we just used one fractional unit. We explored some other options, but right here I want two columns, so I can say 1FR and then 1FR, and that's gonna give me two equally sized columns.

common.css

.squares-wrapper > .squares > .square {
    display: grid;
    grid-template-columns: 1fr 1fr;
}

Now if I hit save, that's going to be the grid layout. It's not really worth looking at yet because the images are simply going to be overriding everything, so let's fix that first. Let's go and we don't have to grab these squares, wrapper squares and square here, because we're never going to be using a image outside of the square wrapper inside of that image wrapper, if that makes sense.

So here, and I'll explain what my choice is here - I'm going to say square and then image wrapper, and then select the image. The reason why I'm going with this choice is because I am never going to use this image wrapper outside of a square. Or I should say the styles that I'm going to be applying here are only for when they're inside of this square class.

Technically I could do squares wrapper and then squares followed by square, but that's really not needed right now, because at the end of the day, the square, whenever I want to have a image wrapper inside of it, is going to have these styles, I'm always going to want it to have these styles.

What I'm going to do here is I'm going to say the width should be 100%. The height should be 500 pixels, and you'll see why I'm doing that here in a second, that's what's going to give us our nice square look. Then after that we need to use a little tool called object fit and then cover. This is an incredibly helpful little attribute, it is very similar to what we did when we added that skew in the top image, where it maintains the aspect ratio of the image and shrinks it down, and essentially crops it, so that it fits inside of whatever container it's inside.

common.css

.square > .img-wrapper img {
    width: 100%;
    height: 500px;
    object-fit: cover;
}

If you hit save now, we should be a little bit closer to what we're looking for. If I hit refresh here, you can see you that is looking really good.

large

Right here you can see that we have these images, they're lining up, they're nice and square, so they are cropped properly, and that's looking excellent. A couple little fixes, obviously we still have to address the content itself. And then also do you see how we have a little bit of a break right here? I'll zoom in so you can see it.

large

Do you see that little bit of margin? That is just due to the default margin provided by HTML. So I'm going to fix that, and let's inspect it and see what values this needs to be set at. So for our image wrapper here, I'm going to ... Let's see, I'm trying to see if I want to apply this to the square or to the image wrapper, and it looks like it's the square that actually needs it.

So in the square I'll say margin top and then let's say -5 pixels, and that's almost there. Let's move it down one more and there we go, -4 pixels is perfect for that square class. Let's copy that value and switch back, this was just in the square class. Hit save, and now we should be good to go.

common.css

.squares-wrapper > .squares > .square {
    display: grid;
    grid-template-columns: 1fr 1fr;
    margin-top: -4px;
}

If you hit refresh, everything should still be working, so that is coming along very nicely. I can tell you from experience, when I was first tasked with building something like this, and this was a number of years ago, the designer gave this kind of checkerboard looking design. This took a while for me to figure out exactly how to build.

We ran through it pretty quickly because I've done this a number of times and I know how to implement this now, but I can tell you that this is a little bit challenging to get perfect if you've never done it before. But the keys are working with that object fit property and then CSS grid. Those two things make this a much easier type of system to build out.

Now that we have all of those items set, now it's time to clean up our heading and our text and everything there. Let's switch back to the code, I have the image wrapper image as the last item, so now let's grab the square text wrapper. To do that I'm going to kind of copy the same process that we followed right above it.

So I'm going to say square and then we'll do the square text wrapper, and inside of this I'm going to make this use a flex box container. I'm gonna justify content in the center, and then align items is also going to be in the center, because remember we want all of the text content to be perfectly centered horizontally and vertically.

I also want the elements to sit on top of each other. So let's see what we have right here. If I hit refresh, do you see how the heading is right next to the content?

large

If you remember that the flex direction by default with flex box is to put items right next to each other in this kind of format, so we need to use the flex direction column. I'll say flex direction and column, and that will fix that value. We also want to add some padding, so let's add padding of 42 pixels.

common.css

.square > .square-text-wrapper {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    padding: 42px;
}

Now if you hit refresh, that is looking much better, you can see that that's really the exact look that we are wanting.

large

The only difference is we want to grab this heading and add a color to it. So we can just copy this, and inside of the square text wrapper for the heading, what I want to do is update the color. Here we'll say the color should be that CEA135.

common.css

.square > .square-text-wrapper h1 {
    color: #cea135;
}

Save, refresh, and there we go, that is looking really nice.

large

We have everything that we need on this page except for the footer, and there's one other thing. Do you see how we have this space right here? Well, that is not ideal. I think I would like to have a little bit more space between our squares and the page content.

But the one issue here is, it'd be pretty straightforward if I just added something like, I could say on the page content, give me a margin bottom of 40 pixels. And that would work, but that means that that margin bottom would be used in every other spot where I use the page content, and I don't want that.

There may be spots where I want it to be more flush, and the same thing with the squares. I could say I want you to take the square wrapper and give it a margin top of 40 pixels, and that would work, but still not exactly what we're really looking for, because then that margin top would follow the squares along everywhere else we used them.

Instead I'm going to create a little helper method here. I'm going to create a special class, and I usually will always have classes like this. Here I'm going to call it our helpers styles and I'm going to add a spacer. Let's add a spacer of, let's say spacer 100 is going to be the class name.

What this is going to do is it's going to give us the ability to have some margin anytime we want. It provides a spacer for us. Here we can just say the height is going to be 100 pixels wide and the width is going to be 100%, something like that.

common.css

/* Helpers */
.spacer100 {
    height: 100px;
    width: 100%
}

Now what we can do is just call this spacer 100, and what I usually do is I'll have a bunch of these. I'll have like spacer 100, I'll have spacer 40, and then anytime that I need to, I can call that. So right here I can come in between and say spacer 100, and then ... Emmett isn't helping me out for some reason, there we go.

large

So I'll just give this empty div here with that class name, and now you can see I have the right amount of space, or I should say I have some space where I didn't before.

large

This is a little bit too much space, so let's actually update this. So I want to have this, let's see what 60 looks like, that looks perfect. So let's change the name of the class, I'm going to change this div to be spacer60. Then I'll come here to the css and this is now going to be a spacer of 60, just like that. The height will be 60 pixels.

common.css

/* Helpers */
.spacer60 {
    height: 60px;
    width: 100%
}

Hit save, hit refresh, and that's looking really good.

large

In this guide you learned how to create a full checkerboard type pattern using CSS grid and flex box, and also how to create little helper classes that help us add some shared style components.