Generating Simple Grid Systems with Sass

November 17, 202110 minute read

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.


1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
1
2
1


HTML

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.


Flexbox is our friend

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.


Generating Classes

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.


Bringing it all together

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!