How to Create a 12 Column Grid System with Sass

Grid systems are an incredibly powerful tool when creating any sort of website. There are many grid systems out there, such as Bootstrap and Zurb Foundation, but it’s actually a lot easier to roll one from scratch than many people think.

If you’re unfamiliar with anything in this tutorial, I highly recommend you have a read of Sass Projects for Beginners. Once you’re a little more up to speed, come back and I’ll show you how to make a 12 column grid system with Sass.

Just a heads up, you’ll need to use a little math in order to work out the spacing. Don’t worry though, once you get the basic idea of how to work out the spacing, you can have Sass automate the calculations for you. Then it’s easier than ever to change and evolve your grid system as your projects become more advanced.


1 The HTML Structure

The HTML structure of our grid system is very straightforward. It doesn’t require any .first or.last classes, so it works really well with dynamic content, like you get with WordPress.

Below is a snippet of how to use a 2 columns, each spanning 6 spaces each. There isn’t much to say about the class names as they’re pretty straight forward. There is a total of 12 columns and you can chain any columns together in a row to make 12. A good example is a column 5 and column 7.

1
2
3
4
<div class="row">
    <div class="col-6">Col #6</div>
    <div class="col-6">Col #6</div>
</div>

Using The Grid

To use the grid, you just need to have all the columns in any given row add up to 12. In the example above, you’ll see 2 col-6 classes, which make 12. If you start with a col-5 class, then you need to either use a col-7 or whatever other number gets you up to 12.

Here are two examples of getting to 12 after starting with a col-5. As you can see, both columns add up to 12:

1
2
3
4
5
6
7
8
9
10
<div class="row">
    <div class="col-5">Col #5</div>
    <div class="col-1">Col #1</div>
    <div class="col-1">Col #1</div>
    <div class="col-1">Col #1</div>
    <div class="col-1">Col #1</div>
    <div class="col-1">Col #1</div>
    <div class="col-1">Col #1</div>
    <div class="col-1">Col #1</div>
</div>

Why ‘row’ and ‘col’?

The point of this grid system is to be nice and simple. That’s one of the reasons you don’t see any .first and .last classes anywhere.

In grid systems like Bootstrap there are names like .col-md-6. Here it’s a lot simpler, so we’re only going to use .col-6. If the grid system was more advanced, then some more classes would be necessary but luckily for us, it’s as simple as can be.


2 The Sass Layout

The Sass is pretty straightforward here and most of it can actually work fine with good old CSS. The reason I’ve used Sass is to make the spacing a little easier to handle and keep the code a little more organised with some (very light) nesting.

Final Sass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//----- Extends
%clearfix:after {
    display:block;
    clear:both;
    content:'';
}
 
//----- Grid System
$grid-spacing:3%;
 
.row {
    @extend %clearfix;
 
    & + & {
        margin-top:$grid-spacing;
    }
}
 
[class^="col-"] {
    float:left;
    margin-right:$grid-spacing;
    -webkit-box-sizing:border-box;
    -moz-box-sizing:border-box;
    box-sizing:border-box;
 
    &:last-child {
        margin-right:0%;
    }
}
 
//----- Columns (Manual)
/*
.col-1  { width:5.583333333333333%; }
.col-2  { width:14.16666666666667%; }
.col-3  { width:22.75%; }
.col-4  { width:31.33333333333333%; }
.col-5  { width:39.91666666666667%; }
.col-6  { width:48.5%; }
.col-7  { width:57.08333333333333%; }
.col-8  { width:65.66666666666666%; }
.col-9  { width:74.25%; }
.col-10 { width:82.83333333333333%; }
.col-11 { width:91.41666666666666%; }
.col-12 { width:100%; }
*/
 
//----- Columns (Automatic)
.col-1   { width:(100% / 12) - ($grid-spacing * 11 / 12); }
.col-2   { width:(100% / 6) - ($grid-spacing * 10 / 12); }
.col-3   { width:(100% / 4) - ($grid-spacing * 9 / 12); }
.col-4   { width:(100% / 3) - ($grid-spacing * 8 / 12); }
.col-5   { width:(100% / 2.4) - ($grid-spacing * 7 / 12); }
.col-6   { width:(100% / 2) - ($grid-spacing * 6 / 12); }
.col-7   { width:(100% / 1.714285714285714) - ($grid-spacing * 5 / 12); }
.col-8   { width:(100% / 1.5) - ($grid-spacing * 4 / 12); }
.col-9   { width:(100% / 1.333333333333333) - ($grid-spacing * 3 / 12); }
.col-10  { width:(100% / 1.2) - ($grid-spacing * 2 / 12); }
.col-11  { width:(100% / 1.090909090909091) - ($grid-spacing * 1 / 12); }
.col-12  { width:100%; }

Grid Variables

There is only one variable set for the grid, and that’s $grid-spacing. As you can imagine from the name, it allows us to keep even spacing across the entire grid system. A big benefit here is that, as the grid becomes more advanced and more spacing elements are needed, we only need to change it in one place.

1
$grid-spacing:3%;

Each Row

Each row of the grid is extended with a clearfix placeholder. This stops the age-old problem where parent elements break if they have floated child elements. You can read more about clearfixes here.

The & + & just means that when one row is followed by another, add some $grid-spacing to the top of the following one. It’s the same as .row + .row in CSS.

1
2
3
4
5
6
7
.row {
    @extend %clearfix;
 
    & + & {
        margin-top:$grid-spacing;
    }
}

Each Column and It’s Spacing

As you’ll see below, each column has some base styling. Take note of the [class^="col-"] part, especially the ^ before the ="col-". This is what’s called an “attribute starts with” selector, it means any element that starts with col- will be affected. It’s incredibly handy when you’re creating something like a grid when every column starts with the same prefix.

Each column also has a box-sizing of border-box. This is done to stop the width of each column changing if padding is added at any point.

1
2
3
4
5
6
7
8
9
10
11
[class^="col-"] {
    float:left;
    margin-right:$grid-spacing;
    -webkit-box-sizing:border-box;
    -moz-box-sizing:border-box;
    box-sizing:border-box;
 
    &:last-child {
        margin-right:0%;
    }
}

How to Work Out Each Column Size

Let Sass do it: If you don’t want to work this out every time the spacing changes, Sass can actually do the calculation for you. Scroll down a little and I explain how to let Sass handle the heavy lifting, then the width automatically adjusts when you change the $grid-spacing value. However, I recommend doing this once you know how it works. Here’s what the self-calculating code looks like below:

1
.col-1 { width:(100% / 12) - ($grid-spacing * 11 / 12); }

I bet when you decided to make websites, you never accounted for all the math involved, am I right? Always keep in mind that, when calculating each column size, it has to add up to 100%.

It all depends on the $grid-spacing and the size of one individual column. From there it’s just some simple adding up. Here’s the guide to get the width of each column:

  1. To find the size of one column, get the $grid-spacing number, in this case it’s 3, times it by 11 and take it away from 100. That gives us 67.
  2. Now divide your answer, it should be 67, and divide it by 12. You should get 5.583333333333333. That’s the size of one column out of 12 with 3% spacing in between each one.
  3. To get the sizes of the other columns it’s just a matter of adding another column, plus 3 spacing. So to get the width of 5 columns, you times 5.583333333333333 by 5 and times 3 by 4, then add them together. Test it out yourself, you should get the answer 39.91666666666667.

Tip: It can be pretty confusing to work this out at first. You need to take into account that, even though there are 12 columns, there are only 11 bits of spacing because the last one hits the very end of the row.

1
2
3
4
5
6
7
8
9
10
11
12
.col-1  { width:5.583333333333333%; }
.col-2  { width:14.16666666666667%; }
.col-3  { width:22.75%; }
.col-4  { width:31.33333333333333%; }
.col-5  { width:39.91666666666667%; }
.col-6  { width:48.5%; }
.col-7  { width:57.08333333333333%; }
.col-8  { width:65.66666666666666%; }
.col-9  { width:74.25%; }
.col-10 { width:82.83333333333333%; }
.col-11 { width:91.41666666666666%; }
.col-12 { width:100%; }

Let Sass Calculate it For You

The problem with the above code is that we have to painstakingly work out each column width. I’ve come up with a basic calculation for Sass to run for us, now we no longer have to work out each value every time $grid-spacing changes.

The below is probably going to be a little confusing if you jumped over the last section which explains how you actually get the width of a single column. Without knowing the above, you can’t create the calculation on your own. So I highly advise you read the above section before trying this bit, otherwise if it breaks you’ll be stuck.

How to calculate a single column width:

1
.col-1 { width:(100% / 12) - ($grid-spacing * 11 / 12); }

You’ll notice that as we get higher, the divided number for $grid-spacing goes down. If you look carefully, this actually the number of single columns it takes to get to 12 from the given number. For example, the .col-5 width takes another 7 columns to reach 12, the $grid-spacing is divided by 7.

1
2
// That 2.4 value simply comes by dividing 12 by 7
.col-5   { width:(100% / 2.4) - ($grid-spacing * 7 / 12); }

Now that’s all well and good, but what about the others? Luckily for you, I’ve gone ahead and written them down. All you need to do is copy and paste:

1
2
3
4
5
6
7
8
9
10
11
12
.col-1   { width:(100% / 12) - ($grid-spacing * 11 / 12); }
.col-2   { width:(100% / 6) - ($grid-spacing * 10 / 12); }
.col-3   { width:(100% / 4) - ($grid-spacing * 9 / 12); }
.col-4   { width:(100% / 3) - ($grid-spacing * 8 / 12); }
.col-5   { width:(100% / 2.4) - ($grid-spacing * 7 / 12); }
.col-6   { width:(100% / 2) - ($grid-spacing * 6 / 12); }
.col-7   { width:(100% / 1.714285714285714) - ($grid-spacing * 5 / 12); }
.col-8   { width:(100% / 1.5) - ($grid-spacing * 4 / 12); }
.col-9   { width:(100% / 1.333333333333333) - ($grid-spacing * 3 / 12); }
.col-10  { width:(100% / 1.2) - ($grid-spacing * 2 / 12); }
.col-11  { width:(100% / 1.090909090909091) - ($grid-spacing * 1 / 12); }
.col-12  { width:100%; }

Final Thoughts

Wow, that was intense. It may take you a while to fully understand how to get each column number, it did for me. Keep at it, and you’ll get there, it just takes a little practice.

There is another side to this that we haven’t touched upon yet, the responsiveness of it. While the grid above isn’t responsive by itself, you can make it responsive with a few edits and some extra leg-work. Let me know in the comments if you’d like to see a follow-up to this tutorial showing how to make it responsive.

If you have any questions, please feel free to ask me in the comments below and I’ll do my best to answer/explain it for you.

This DEMO