Author: Ben Bozzay
Today we’ll learn the best way to create a grid to easily display content, like Wordpress posts, with minimal media queries required for the responsive views.
We frequently see websites using a multi-row setup to organize similar content:
<div class="row">
<div class="col">
...
</div>
<div class="col">
...
</div>
</div>
<!--next row-->
<div class="row">
<div class="col">
...
</div>
<div class="col">
...
</div>
</div>
Using multiple rows complicates the responsive layout significantly:
Two rows with 5 columns in each row
Notice how extra whitespace is created in responsive views due to columns being separated into rows. The columns don’t fill up the remaining space, so some screen sizes have an odd looking whitespace.
On mobile, some columns appear to have a bigger vertical whitespace because of the row’s margin-bottom
. This looks sloppy!
We could adjust the media queries for the rows and columns, but this requires a lot of tweaking to get right.
Using flexbox, we can easily create a responsive grid:
*View the codepen for this grid.
In many situations, you’d want to use Ajax-load-more or filters to dynamically display content on a page, so a grid-layout would be needed.
For example, as part of our web presence overhaul for {code}, Open Source at Dell Technologies, we created a page for dynamically displaying posts based on filter and sorting options.
We created a grid layout so that posts could easily be appended without breaking the layout. In this tutorial, you’ll learn how to re-create this post grid.
Making the grid items responsive is easy using Flexbox.
Let’s examine the wrapping elements:
.container {
max-width: 1335px;
margin: 0 auto;
}
.grid-row {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
}
Our container CSS sets the total max-width. Using display: flex
, our grid-row stretches to the full size of the container.
We use flex-flow: wrap
to designate that child divs (our columns/grid-items) should wrap if they exceed the width of the row. Then, flex-flow: row
means our grid-items will flex from left to right. If we used flex-flow: column
, our child divs would flex from top down.
*Source: https://css-tricks.com/almanac/properties/j/justify-content/`
Then, we use justify-content: flex-start
because we want our grid-items to line up next to each-other at the start of the row.
Each grid-item should have identical height, so we set a height of 550px:
.grid-item {
height: 550px;
flex-basis: 20%;
-ms-flex: auto;
width: 259px;
position: relative;
padding: 10px;
box-sizing: border-box;
}
On desktop views, we set a flex-basis of 20% for each grid-item. This means that 5 grid-items will display on the same level. The 6th grid-item will wrap to the next “row” since we are using flex-wrap: wrap
in our grid-row.
We set a width of 259px for certain browsers that require a width to be defined. However, the actual width is set by flex-basis.
We only need a few media queries on our .grid-item
. We just need to define the flex-basis on each desired screen-width.
Based on the content within our grid-items, we used these media queries:
.grid-item {
height: 550px;
flex-basis: 20%;
-ms-flex: auto;
width: 259px;
position: relative;
padding: 10px;
box-sizing: border-box;
}
@media(max-width: 1073px) {
.grid-item {
flex-basis: 33.33%;
}
}
@media(max-width: 815px) {
.grid-item {
flex-basis: 50%;
}
}
@media(max-width: 555px) {
.grid-item {
flex-basis: 100%;
}
}
On the smallest screen-width, we use a flex-basis of 100% to make our grid-item the full-width of the grid-row.
If you’re building for mobile-first, you should adjust your CSS this way:
.grid-item {
height: 550px;
flex-basis: 100%;
-ms-flex: auto;
width: 259px;
position: relative;
padding: 10px;
box-sizing: border-box;
}
@media(min-width: 1073px) {
.grid-item {
flex-basis: 33.33%;
}
}
@media(min-width: 815px) {
.grid-item {
flex-basis: 50%;
}
}
Our .grid-item defaults to a flex-basis of 100% unless the screen size is a large tablet or a laptop/desktop.
With either approach, we only need to change the flex-basis for a few screen-widths to achieve a grid.
The CSS in this tutorial doesn’t cover all of the vendor prefixes required when using flexbox. If you’re using a build tool like Webpack or Vite, make sure you use PostCSS with autoprefixer to automatically add all the required vendor prefixes to your compiled CSS files.
If you aren't using any tooling, you can also generate these vendor prefixes by pasting your CSS into an autoprefixer tool like this one.
View the full source code, which also includes the styles for the content in each grid-item and the hover/grow effects.