You'll need to have a project up and running with Sass (SCSS) and will hopefully have a variables folder with some Sass partials in it. In your 'variables' directory add a new sass partial and call it something like "_gutters.scss". Open the file and add a variable so that we have a gutter (width of your choice) to work with. The sass will look something like this:
$gutter-width: 40px;
Now that we have a gutter width stored in a variable (so that we can easily change it later if required) we can move on to setting up the grid framework. This is done via a sass mixin. Personally I store my mixings in the 'abstractions' directory but you may have your own preference. The main thing is to make sure that your mixins are the first thing that are compiled before you start working on any production code. So in my 'abstractions' directory I'll create another sass partial and call it something like "_mixins.scss". Open the file and create a mixin:
@mixin grid-span($columns) {
$gutters: ($columns - 1);
flex-basis: calc((100% / #{$columns}) - ((#{$gutter-width} * #{$gutters}) / #{$columns}));
flex-grow: 0;
flex-shrink: 0;
width: calc((100% / #{$columns}) - ((#{$gutter-width} * #{$gutters}) / #{$columns}));
}
Whoa?!?! What the heck is going on here? If this looks utterly alien to you - never fear. I'll explain what's going on here.
Firstly we've created a mixin (a block of code which we can use again and again by entering a variable. First of all let me give you an example of how we would call this code:
.foo {
display: flex;
.bar {
@include grid-span(3);
margin-right: $gutter-width;
&:nth-child(3n) {
margin-right: 0;
}
&:last-child {
margin-right: 0;
}
}
}
What this is doing is telling the parent wrapper that we want to display flex which then makes all child items 'flex items'. This allows us to give them flex properties that make them behave in a grid like format but filling these properties out time and time again is frustrating and not time-efficient.
So, enter our mixin. As you can see we called the mixing using the code:
@include grid-span(3);
What this is doing is saying we want to include the code we've written in our mixin and to pass the value of three to the variable within the mixin. So let's show what that would look like in static code:
@mixin grid-span(3) {
$gutters: (3 - 1);
flex-basis: calc((100% / 3) - ((#{$gutter-width} * #{$gutters}) / 3));
flex-grow: 0;
flex-shrink: 0;
width: calc((100% / 3) - ((#{$gutter-width} * #{$gutters}) / 3));
}
Hopefully this is now looking less scary. Now we've passed '3' as a value to the $columns variable we will also have a fixed value for the $gutters variable as this is formed of a calculation which subtracts 1 from the $columns value. We also defined our $gutter-width variable so we can swap that out for a value and start to make sense of what's happening inside this mixin:
@mixin grid-span(3) {
$gutters: (3 - 1);
flex-basis: calc((100% / 3) - ((40px * 2) / 3));
flex-grow: 0;
flex-shrink: 0;
width: calc((100% / 3) - ((40px * 2) / 3));
}
So now the mixin has all the values it needs and in sass we'd now be looking at this if we'd written this statically:
.foo {
display: flex;
.bar {
flex-basis: calc((100% / 3) - ((40px * 2) / 3));
flex-grow: 0;
flex-shrink: 0;
margin-right: 40px;
width: calc((100% / 3) - ((40px * 2) / 3));
&:nth-child(3n) {
margin-right: 0;
}
&:last-child {
margin-right: 0;
}
}
}
So let's tackle the calculation so we know what's happening: