Building your own frontend framework from scratch — 5. The Grid

Thabo T
Simple Frontending

--

Grids are popular web structures that are used to layout content in a neat and consistent way. Grids have been getting more complex with a bunch of features which people mostly never use. But getting a simple, flexible grid up and running doesn’t need more than 60 lines of code.

First here’s a simple diagram of what we want to achieve.

Container

A container holds one or many rows. Its children should only be rows. Our container has a max width of 1200px, but we add a ‘fluid’ option so that it can go across the whole page on larger screens if need be. So what does that look like in code? Firstly lets create a new file called src/sass/_grid.scss and lets import it into src/sass/app.scss . So now src/sass/app.scss should look like:

@import "normalize";
@import "boilerplate";
@import 'config/fonts';
@import 'config/colours';
@import 'config/site';
@import 'base';
@import 'grid';

Cool, now inside src/sass/_grid.scss let’s set up our container. Here’s what it looks like:

.gf-container {
width: 100%;
margin: 0 auto;
max-width: 1200px;
&--fluid {
max-width: 96%;
}
}

Let’s start from the top with gf-container . The gf is just a namespace. We use it so it doesn’t clash with other libraries if we ever use more than one in a project. And because this is Griffin UI, I just made it gf . It can be anything you like, preferrably 1–3 letters. width: 100% will default it to the full page width, but max-width: 1200px will make sure it doesn’t go over 1200px. margin: 0 auto centers the container. &--fluid is exactly the same as writing another css rule that looks like this:

.gf-container--fluid {
max-width: 96%;
}

Sass gives us nice shorthand like this so we don’t have to keep writing out the same class definitions.

Row

Rows are containers for columns. Our rows rely a lot on flex. Here’s what rows look like for us in the code:

.gf-row {
display: flex;
flex-direction: row;
justify-content: flex-start;
flex-wrap: wrap;
margin-bottom: $grid-row-vmargin;
align-items: flex-start;
}

Explaining what is happening here is a deeper discussion that is probably easier to understand if you look at this explanation about Flex. But basically this is creating a comfortable home for our columns. $grid-row-vmargin is a variable we have set in _sites.scss to set the vertical distance between each row.

Column

Columns are the children of rows. These are the little containers that allow us to separate our content into neat little block of varying width. The code for this is also fairly simple and looks like this:

.gf-col {
padding: $grid-gutter;
box-sizing: border-box;

&-auto {
flex: auto;
}
&--vspace {
margin-bottom: $grid-col-vmargin;
}
}

Notice with this, we haven’t set a width. That’s because we’re going to dynamically generate the classes for the widths of the columns with one of sass’s useful functions:

@for $i from 1 through $grid-size {
.gf-col-#{$i} {
width: calc(100%/#{$grid-size} * #{$i});
}
}

where $grid-size is a new variable we are creating to set the size of our grid. In this case I’ve made it a 16 column grid. This will generate these classes:

.gf-col-1 {
width: calc(100%/16 * 1);
}
.gf-col-2 {
width: calc(100%/16 * 2);
}
.gf-col-3 {
width: calc(100%/16 * 3);
}
....gf-col-16 {
width: calc(100%/16 * 16);
}

calc is function in css (not sass) that allows us to do basic maths calculations. As you can see the number of columns dictates how much space is taken up along the x-axis, otherwise known as the width. So 1 column is 100% of our available width, divided by the total number of columns, which is 16, multiplied by 1. And 16 columns is 16 times that number.

But because we also want to this grid a little bit more flexible, we can use it to harness the power of flexbox. So lets generate some more classes that will allow this:

@for $i from 1 through $grid-size / 2 {
.gf-col-flex-#{$i} {
flex: #{$i};
}
}

As we did above it’s going to generate classes gf-col-flex-1 to gf-col-flex-8 , because we say $grid-size / 2 . A full 16 is unnecessary and I’ll show you why in a bit. So this function will generate:

.gf-col-flex-1 {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
.gf-col-flex-2 {
-webkit-box-flex: 2;
-ms-flex: 2;
flex: 2;
}
.gf-col-flex-3 {
-webkit-box-flex: 3;
-ms-flex: 3;
flex: 3;
}
....gf-col-flex-8 {
-webkit-box-flex: 8;
-ms-flex: 8;
flex: 8;
}

The first weird thing is all the webkit / ms stuff. That’s the work of the auto-prefixer that is part of the compilation process. Flex is relatively new, and not fully adopted as flex . Webkit pertains to webkit based browsers, like chrome and opera. MS is Microsoft(internet explorer). But generally just flex is (should be) safe these days. So anyway the flex value represents a ratio of space to be used within a row. So if I had a row and it had three cols . The first col was flex: 5 , the second was flex: 3 and the last was flex: 1 , then the width of each would be divied up in that ratio. So in total we have5 + 3 + 1 = 9‘columns’. So flex: 5 will take up 5/9 of the space and so on. Given our grid and the classes we generated, we have our grid which looks like this:

Not too shabby for a few lines of code. we also had to add some utility classes so we could display the grid lines. So I have set up a github repo which you can use to refer to the code. But before you do that let’s create this Grid page. When building projects like these it’s always a good idea to document what you’re doing. So let’s create a new folder called src/docs and in it we’ll create a file called grid.html . We now also need to make a change to our Gulpfile.js . Currently it’s listening for changes in direct children .html files before it recompiles. But we want it to listen to all our .html files, whatever folder they’re in. So in Gulpfile.js on line 53 lets change:

gulp.watch("./src/*.html").on('change', browserSync.reload);

to

gulp.watch("./src/**/*.html").on('change', browserSync.reload);

Now it will listen to changes in all .html files, no matter how many folders we create.

Cool. So let’s add this grid code to our grid.html file. You can also change it as much as you like and create as many combinations as you like. It’s quite fun really, especially since you wrote the code that does that! Also doing a bunch of combinations shows you where you have have gaps/bugs.

Anyway let’s add this to grid.html

This is the code that generates the grid image before it. If not, then I’ve missed an explanation step, or you messed up. I can’t take the blame for everything you know.

Wow, we built a flippin’ grid! That actually deserves a drink. Now it’s going to start getting interesting as we start fleshing out the rest of this framework!

*** You can reference the code at https://github.com/thabotitus/griffin-ui

--

--