
Grid Layouts with SCSS and Flexbox
With the advent of the grid property in CSS, many of the headaches attempting to achieve a unifying grid layout have been solved. Though there still remains some cases when it is necessary to leverage a flexbox grid. Flexbox is supported in more browsers and it is easier to achieve certain things such as alignment of the grid columns. We will go more into that later.
Let's start with the HTML.
<div class="grid">
<div class="column">
<div class="inner">
<div class="card">
<div>Card header</div>
</div>
</div>
</div>
<div class="column">
<div class="inner">
<div class="card">
<div>Card header</div>
</div>
</div>
</div>
<div class="column">
<div class="inner">
<div class="card">
<div>Card header</div>
</div>
</div>
</div>
</div>
The HTML is fairly simple. Nothing too wild going on. Now let's take a look at the mixin that will apply our grid layout.
@mixin flexGrid($gutter: 20px) {
display: flex;
margin-top: (-$gutter);
margin-left: (-0.5 * $gutter);
margin-right: (-0.5 * $gutter);
flex-wrap: wrap;
}
@mixin flexGridItem($gutter: 20px, $col: 2) {
flex: 1 0 100%/$col;
max-width: 100%/$col;
width: 100%/$col;
padding: 0 $gutter/2;
margin-top: $gutter;
> * {
height: 100%;
}
}
The flexgrid mixin will apply the `display: flex` to our grid. As a parameter we pass in a gutter variable. This is responsible for the spacing between each of our columns. From there, it calculates the margins to ensure all of the columns are equally distant while being flush against whatever constraining parent container
The flexGridItem mixin should take in the same gutter value we used for the flexGrid mixin. The $col parameter is how many columns across we want the grid. This column number is divided across the flex which gives us our column spacing where we render the actual content. Now let's see it in action.
.grid {
@include flexGrid(30px);
.column {
@include flexGridItem(30px, 3);
}
.card {
background: white;
height: 300px;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 9px 0 rgba(0, 0, 0, 0.3);
}
}
Using the following scss will give us something that looks like the following:

We can actually further add to this by incorporating media queries and have a different number of columns to render at certain breakpoints.
For example, let's have it become one column on mobile, two columns on tablet, and three columns on desktop.
.column {
@include flexGridItem(30px, 1);
@media (min-width: 767px) {
@include flexGridItem(30px, 2);
}
@media (min-width: 1023px) {
@include flexGridItem(30px, 3);
}
}
By simply updating the column value for each breakpoint, we have achieved different columns across depending on the breakpoint.
Lastly, you may have noticed on our tablet breakpoint, we have two across and the third card is flush along the left side. Wouldn't it be nice if we could just center it? This is actually extremely easy with flexbox, and much more of a challenge using CSS grid.
We can center the last column on the last row by just adding justify-content: center; to our .grid class.
And that's it! We can create responsive grid using flexbox only with a few lines of code.

