CSS Grid Brick Pattern

Tue Jan 30 2024

Image of a red brick wall

If you’re just beginning your CSS journey, I highly encourage you to study Flexbox and Grid. In my opinion, CSS-TRICKS has some of the best resources on Flexbox and Grid. These powerful tools are used to create and control the layout of elements on a webpage. It’s a bit of an oversimplification, but when learning, you can think of Flexbox as being for one-dimensional layouts and Grid for two-dimensional layouts.

What are we making?

In this post, I’m going to show you how to create the brick-like pattern I use to diplay blog cards on the desktop version of the blog index page of this website. In case you’re on mobile, here’s what it looks like:

Achieving this is pretty straightforward except for bit of CSS math.

The HTML

We’ll need a wrapper div and any number of child elements.

<div class="wrapper">
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  ...
</div>

The CSS

Here are the key styles for the wrapper element.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* ↑ equivalent to ↓ */
  grid-template-columns: 1fr 1fr 1fr;
}

Obviously, we need to set the display property to grid, but less obvious is that we need a total of three columns. I’m using the fractional unit fr to specify that I want three columns of equal width, but any unit will do. The simplest way to explain why we need three columns is to open up the developer console and inspect the grid layout. This is what it will look like:

Image of the grid layout showing the row and column lines

Notice that some of the elements span across two columns, while others only span across a single column. By default, all grid children take up exactly one column and one row. To override this, we can use the css property grid-column, which we set on the child element.

.card {
  grid-column: span 2;
}

The tricky part for me was nailing down the pattern for setting this property only on the right child elements. By going through and counting each element, I figured out that I needed to set grid-column: span 2 on every fourth element starting from zero and one. We can achieve this with vanilla CSS using the :nth-child() pseudo-class and its functional notation.

.card:nth-child(4n) {
  grid-column: span 2;
}

.card:nth-child(4n + 1) {
  grid-column: span 2;
}

:nth-child(4n) selects every fourth child beginning at zero and :nth-child(4n + 1) selects every fourth child beginning at one:

If it looks a lot like y = mx + b that’s because it is!

n =4n =4n + 1 =
00th child1st child
14th child5th child
28th child9th child
312th child13th child
416th child17th child

Here’s the whole CSS block, nested:

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  .card:nth-child(4n),
  .card:nth-child(4n + 1) {
    grid-column: span 2;
  }
}

I hope you found this interesting! Have fun playing around with different values for column width or adapt this code to work for more than two visual columns!


View the MDX for this page or submit an issue if you noticed any errors!