by Daniel, on 17th Sep, 2013

Building a Responsive Grid Generator with SASS

Hello All,

Today I thought I would dive right in and explain what I have been trying to achieve - which is creating my very own responsive grid layout with as little bloat as possible. There are many, many other grids, frameworks, libraries out there already such as bootstrap and Semantic UI. Both are brilliant frameworks and I thoroughly recommend them however responsive design is something I have been intrigued with for a long time and there is no better way to learn about something than by doing.

If you would like you can check out the demo or alternatively download the source files here.

When beginning this project I had only intended to build my own small (static) framework for use internally within the small team of developers/designers we have here @ Forrk however as I was writing my SASS I began tweaking/improving the code in such a fashion that it soon became possible to create any type of responsive grid by simply changing a few variables denoted at the beginning of the script. This enables me to use this base for all new projects without having to spend time customising the grid or spending an age cursing at the screen with frustration.

So without further adue please see below my full code. We will tackle the SASS/CSS first :

A good backbone

body, html
{
    margin:0;
    padding:0;
}
img
{
    max-width:100%;
}
.container
{
    max-width:1200px;
    margin:0 auto;
    min-height:1px;
}
.row
{
    width:100%;
    &:after
    {
        clear:both;
        display:block;
        content:'';
        line-height:0; 
    }
    [class*="block"]
        {
        display:block;
        float:left;
        margin-left:$margin;
        &:first-of-type
        {
            margin-left:0 !important;
        }
    }
}
Essentially this is the backbone of the grid. This is where the whole thing comes together. The '.container' element can of course be styled in any way you like. I have no fixed width but added a max-width to prevent gargantuan containers on larger screen resolutions but this is optional and you can remove a maximum option completely or even set a fixed width. The blocks (as I have named them are container inside a 'row' which spans the entire width of its parent. We also have the attribute selector [class*="block"] which targets any elements whose class attribute contains "block". Using this universal selector for "block" will save us time, code and therefore file size for our production CSS file. One other thing to note is the &:first-of-type selector which removes any margin from our first block. The important thing to note about this is that it will NOT work in IE8 or less, you could alternatively add a class of first to each first block and remove the margin using this selector. E.g
[class*="block"]
{
     .first
     {
            margin-left: 0 !important;
     }
}

Your subsequent HTML will look something along the lines of this (dependant on the number of columns you denote)

    
Block 5
Block 5

Calculating the widths

Here is where we do the smart stuff, generating the widths and margins for our grid. At the top of our SASS file I have two variables and a a function. The variables are completely interchangeable however it is important to remember abnormally large margins and a high number of columns may break your layout. A margin of around 1.5-3% is the equivalent of 20/30px on a standard size screen. Most popular frameworks use values within this range.

The reason it breaks the layout is simple, take the values of:

$columns : 33;

$margin: 5%;

Here we are saying we want 10 columns of equal width. So 100% / 33 gives us 3.03030303%, we then want a margin of 5% so this is removed from our width leaving us with -1.969696969697%. Now as each block increases in size this total is multiplied by the size of the block and a margin offset, which will infact by the second block return us to positive integers however it is safe to remember the below formulae to be safe.

$columns * $margin should never equate to more than 100 and should ideally remain below 70. This should leave ample amounts of flexibility and indeed it is certainly impossible to implement a responsive grid system where each block is of an equal (relevant) size & $columns * $margin equates to more than 100%.

Creating the grid

After the variables are set there is a function which calculates (from within a SASS) the relevant width of each block. I will not bore you with ins and outs as each line is commented for full explanations.

@function calculateBlock ( $number: 1, $margin: $margin)
{

    /* find base width of individual columns - set margin */
    $calc : (100%/$columns*$number)-$margin;
    
    /* divide margin by num of columns */
    $margin-divide: $margin/$columns;
    
    /* return width of block by base width calculated plus margin divisible * block number*/
    @return $calc + ($margin-divide*$number);

}
Now in order to actually create the blocks we need a simple SASS loop which creates a class with the name 'block+num' for however many columns you have set. Once the class is created we use the calculateBlock function explained above to return a percentage width :
    @for $i from 1 to $columns+1
    {
        $width : calculateBlock($i);
        .block#{$i} { width:$width }
    }

Responsive Media Queries

To complete the structure I have included (completely optional) media queries which slightly alter the grids behaviour at particular sizes. The SASS can be found below. Essentially what I am doing is setting the container to 85% width below a screen resolution of 1200px. At 800px or below I am decreasing the size of each block slightly and increasing the margins to help prevent content bunching. At 550px or below, which I think of as targeting mobiles (although targeting devices by screen resolution is certainly not fireproof) I set all blocks to span the entire width of the container. I add 20px padding either side to the container to center it and ensure content isn't pushed up against the edge of the screen.

@media (max-width : 1200px)
{
	.container
	{
		max-width:85%;
	}
}
@media (max-width: 800px)
{	
	@for $i from 1 to $columns+1
	{
		$halfWidth : calculateBlock($i, $margin * 1.75);
		
		.block#{$i} { width:$halfWidth; }
	}
	[class*="block"]
	{
		margin-left:$margin * 1.75 !important;
	}
}
@media (max-width: 550px)
{
	.container
	{
		width:100%;
		padding:0 20px;
	}
	[class^="block"]
	{
		width:100% !important;
		float:none !important;
		margin:0 0 0 0 !important;
	}
}

You can view my example grid here or alternatively download the source files here. Remember once you have downloaded them you only need to change the $column & $margin variables inside of the SASS, once compiled it will generate the relevant CSS grid for you.

request a callback

Why not check us out on some of our social networking accounts. Alternatively, if you would prefer to contact us directly, you can always drop us a line below or on hello@forrk.co.uk or tell us about your project and get a quote.

GET A QUOTE Back to top