In this tutorial, I'll be walking you through one way to create a dynamic grid system using Sass mixins. Generating grid systems with Sass can be a powerful and simple way to set up a custom grid for your project with ease.
The markup for our grid is going to look something like this:
<div class="grid">
<div class="grid__col-6">I'm column one</div>
<div class="grid__col-6">I'm column two</div>
</div>
.grid
is required as a wrapper and each child div is defined by having a .grid__col-X
class, where x represents how many columns the div should fill.
Let's start by establishing a flex-based grid class to use as our wrapper. I'm using the BEM styling convention here - if you’re unfamiliar feel free to read more about it!
$gutter: 12px;
.grid {
margin: auto;
display: flex;
flex-wrap: wrap;
&__col {
box-sizing: border-box;
margin-right: $gutter;
&:last-child {
margin-right: 0;
}
}
}
Above we create a variable to keep track of how much gutter we want between each column. We also create a global style for all the child columns giving them a margin-right equal to whatever gutter was set above.
Now for the fun part! Below is a mixin that takes a number of columns and generates all the classes needed to make the grid system function.
@mixin grid-generator($grid-columns) {
@for $i from 1 through $grid-columns {
.grid__col-#{$i} {
@extend .grid__col;
width: calc(#{percentage($i / $grid-columns)} - #{$gutter} + (#{$gutter} / #{$grid-columns} * #{$i}));
}
.grid__offset-#{$i} {
margin-left: percentage($i / $grid-columns);
}
}
}
The width calculation is rather verbose, as it has to accommodate for the missing margin on the last column in the row. It also provides a .grid__offset
class for off setting columns.
The final step is to call your mixin an reap the benefits! Your final .scss file should look something like this:
$gutter: 12px;
.grid {
margin: auto;
display: flex;
flex-wrap: wrap;
&__col {
box-sizing: border-box;
margin-right: $gutter;
&:last-child {
margin-right: 0;
}
}
}
@mixin grid-generator($grid-columns) {
@for $i from 1 through $grid-columns {
.grid__col-#{$i} {
@extend .grid__col;
width: calc(#{percentage($i / $grid-columns)} - #{$gutter} + (#{$gutter} / #{$grid-columns} * #{$i}));
}
.grid__offset-#{$i} {
margin-left: percentage($i / $grid-columns);
}
}
}
@include grid-generator(12);
Using this you can generate the grid to any resolution you'd like. Have fun making absurd unnecessary grids with thousands of columns!