Introducing the LESS CSS Grid

by on 13th October 2010 with 45 Comments

In the past we’ve taken a look at several CSS grid systems. We’ve also gone over how LESS.js can add a lot of flexibility to the way you style web pages. Today we’re going to combine these two ideas and create a grid system that utilizes LESS.

Read on to see why on Earth we would do such a thing. If you understand the concept, you can also skip the tutorial and go straight to the download. Let’s get started.

Demo and Download

Feel free to download the files and modify/use them however you wish. Just remember to compile your LESS file into a CSS file before actually using the framework on a live site.

View Example
Download LESS CSS Grid

screenshot

Why LESS?

Many of you are no doubt wondering why someone would combine a CSS framework with LESS. Here we have two separate and equally confusing tools that half the developer company either hates or doesn’t understand and I decide to go and wrap them together to create one giant confusing mess!? This will surely insight a riot.

However, despite the fact that plenty of developers would never use such a tool, a LESS-driven grid system makes a lot of sense. Currently, grid systems are fairly rigid. You usually either choose from a couple of different downloads or use an online grid-builder to tweak your options. However, once you’ve already got your download, it can be a real pain to tweak the way the grid works.

Because LESS allows you to insert variables into your CSS, we can use it to build a framework that is easily customizable during the development stage. The goal will be to create something that allows custom grid widths with very little effort.

The grid system we’ll be building today will focus on two variables seen in every other system: column width and gutter width. In conjunction, these two make up the basis for the overall look of the grid and are in fact a primary source of many arguments. If developers can’t decide over what widths the columns and gutters should have, I say let’s leave it open for each developer to decide on a per-project basis.

On a practical level, this means you could use the same grid system for 10 different projects and come up with 10 very different results. This goes a long way towards alleviating some of the rigid structure imposed on your designs by a given grid system.

In the end we should have a system that allows the developer to choose a custom column width and gutter width that will change the entire flow of the layout by changing only two numbers in our CSS.

Am I First Person to Attempt This?

In all honesty, I’m probably not the first person to combine LESS and a CSS framework. However, it’s still a great learning experience that will in the end provide you with a stronger grasp of how both tools work.

Getting Started: The 1Kb Grid

Rather than building the entire project from scratch, I decided to find an existing grid system and modify it to work with LESS. This will work with any system but for the sake of simplicity in this tutorial I chose the 1Kb CSS Grid.

The reason I picked this system is obvious: its size. 960 GS and Blueprint CSS are fine and dandy, but are quite unwieldy and would take much longer to integrate LESS into. With the 1Kb Grid, we can easily view all the CSS in one shot and fully comprehend the changes without too much strenuous explanation.

In fact, here’s the entire CSS for the 1Kb grid at 960px wide with 12 columns and a gutter width of 20px (10px on each side).

/* ================ */
/* = The 1Kb Grid = */
/* 12 columns, 60 pixels each, with 20 pixel gutter */
/* ================ */

.grid_1 { width:60px; }
.grid_2 { width:140px; }
.grid_3 { width:220px; }
.grid_4 { width:300px; }
.grid_5 { width:380px; }
.grid_6 { width:460px; }
.grid_7 { width:540px; }
.grid_8 { width:620px; }
.grid_9 { width:700px; }
.grid_10 { width:780px; }
.grid_11 { width:860px; }
.grid_12 { width:940px; }

.column {
	margin: 0 10px;
	overflow: hidden;
	float: left;
	display: inline;
}
.row {
	width: 960px;
	margin: 0 auto;
	overflow: hidden;
}
.row .row {
	margin: 0 -10px;
	width: auto;
	display: inline-block;
}

That’s all there is to it! I love the simplicity of smaller grid systems without all the extra framework fluff like CSS resets, text styles, and the like. This provides the perfect starting point for our LESS experiment.

Working With LESS

If you need a LESS.js refresher, check out our recent tutorial. You’ll need to have a basic understanding of LESS and how to work with it to proceed, but for those of you who have at least seen it before, I’ll briefly explain what you need to know.

Use .LESS not .CSS

The CSS file that you create should have a .LESS extension instead of the typical .CSS. Remember to link to this file properly in the head portion of your HTML.

In addition, you’ll need to insert a link to the LESS JavaScript file. To make things easy, just copy and paste the two lines below:



When you’re all finished, you’ll want to compile your .LESS file into a .CSS file. This sounds complicated but is actually a completely automated process using Less.app.

Declaring Variables

In LESS, variables are declared using the “@” symbol. Just as in JavaScript, you can perform mathematical operations on your variables in a number of ways.

@columnWidth: 60px;
@doubleWidth: @columnWidth * 2;

You can then insert variables anywhere you would normally place the value that it holds.

.someClass {
	width: @columnWidth;
}

The Math

Before we start modifying the 1Kb grid, we need to understand how it works. In our current version there are 12 columns, each with a width of 60px and a gutter of 10px on both the left and right sides.

It’s a bit confusing, but somehow this all has to add up to a total of 960px wide. Fortunately, there’s an awesome and free online tool that can help us figure out all the nitty gritty math: Instacalc.

Meet Instacalc

Instacalc is a great online calculator that is perfect for programmers, not only because of the instantly updating results but because it allows you to use variables and easily see if your math is working out the way you want it to.

Below, I used Instacalc to plot out the variables we’ll need in our LESS file by starting with the standard 1Kb numbers. Remember that we want the whole system to hinge on two values so that it only takes a second to customize.

screenshot

Even in this form, the math might be a little confusing but it’s actually quite simple. First, we set the width of our columns to 60 and the width of our gutter to 10. Then we simply add together the width of all twelve columns plus all the gutter width (we double the gutter width because it appears on each side of every column). As you can see, in the end we land right at 960, indicating that we did everything right.

As you can see in the image below, we can now change the first two values to anything we want, and the rest update automatically. Our variable width system is up and running!

screenshot

Declaring The Variables

Now that we’ve got the variables and math worked out in a place where we can see them working, it’s time to plug them into our LESS CSS. Insert the following snippet at the top of your LESS file.

@columnWidth: 60px;
@gutter: 10px;

@allColumns: @columnWidth * 12;
@allGutters: (@gutter * 12) * 2;
@totalWidth: @allColumns + @allGutters;

As you can see, this is exactly what we did with Instacalc. Our column width has been set to 60px, our gutter is 10px (which results in a 20px gutter) and our total width equals the width of the gutters plus the width of the columns.

All we’ll have to do each time we want to change the framework is type in new values for the first two variables. The rest of the framework will update automatically based on what we do next.

Creating the Grid Classes

The next step is to insert the variables we just created into the classes that make up the 1Kb grid. Here’s the original code:

.grid_1 { width:60px; }
.grid_2 { width:140px; }
.grid_3 { width:220px; }
.grid_4 { width:300px; }
.grid_5 { width:380px; }
.grid_6 { width:460px; }
.grid_7 { width:540px; }
.grid_8 { width:620px; }
.grid_9 { width:700px; }
.grid_10 { width:780px; }
.grid_11 { width:860px; }
.grid_12 { width:940px; }

To modify this, we’ll start simple. The grid_1 class width is simply set to the columnWidth variable. The grid_2 class is twice as wide and now contains extra gutter space for the new column. These amounts simply increase as you go farther: the column width multiplier increases by one each time and the gutter width multiplier increases by two each time.

.grid_1 { width: @columnWidth; }
.grid_2 { width: (@columnWidth * 2) + (@gutter * 2); }
.grid_3 { width: (@columnWidth * 3) + (@gutter * 4); }
.grid_4 { width: (@columnWidth * 4) + (@gutter * 6); }
.grid_5 { width: (@columnWidth * 5) + (@gutter * 8); }
.grid_6 { width: (@columnWidth * 6) + (@gutter * 10); }
.grid_7 { width: (@columnWidth * 7) + (@gutter * 12); }
.grid_8 { width: (@columnWidth * 8) + (@gutter * 14); }
.grid_9 { width: (@columnWidth * 9) + (@gutter * 16); }
.grid_10 { width: (@columnWidth * 10) + (@gutter * 18); }
.grid_11 { width: (@columnWidth * 11) + (@gutter * 20); }
.grid_12 { width: (@columnWidth * 12) + (@gutter * 22); }

Now, this works as is but if you wanted to simplify things further you could use a Mixin to handle all that messy code. This is much cleaner in my opinion:

.theWidth (@theColumn: 1, @theGutter: 0) {
  width: (@columnWidth * @theColumn) + (@gutter * @theGutter);
}


.grid_1 { .theWidth(1,0); }
.grid_2 { .theWidth(2,2); }
.grid_3 { .theWidth(3,4); }
.grid_4 { .theWidth(4,6); }
.grid_5 { .theWidth(5,8); }
.grid_6 { .theWidth(6,10); }
.grid_7 { .theWidth(7,12); }
.grid_8 { .theWidth(8,14); }
.grid_9 { .theWidth(9,16); }
.grid_10 { .theWidth(10,18); }
.grid_11 { .theWidth(11,20); }
.grid_12 { .theWidth(12,22); }

Finalize the CSS

To finish off the CSS, we have to insert the gutter variable in the column width and nested row section and the totalWidth variable in row class. Remember that the entire point of the exercise is to replace these static numbers with variables that will update automatically any time we make a change to the column and gutter width.

.column {
	margin: 0 @gutter;
	overflow: hidden;
	float: left;
	display: inline;
}
.row {
	width: @totalWidth;
	margin: 0 auto;
	overflow: hidden;
}
.row .row {
	margin: 0 (@gutter * -1);
	width: auto;
	display: inline-block;
}

That’s it! We’re completely finished outlining our framework.

Putting It All Together

Now that we’ve explained all the steps, here’s the finished LESS file all in one shot:

@columnWidth: 60px;
@gutter: 10px;

@allColumns: @columnWidth * 12;
@allGutters: (@gutter * 12) * 2;
@totalWidth: @allColumns + @allGutters;

.theWidth (@theColumn: 1, @theGutter: 0) {
  width: (@columnWidth * @theColumn) + (@gutter * @theGutter);
}


.grid_1 { .theWidth(1,0); }
.grid_2 { .theWidth(2,2); }
.grid_3 { .theWidth(3,4); }
.grid_4 { .theWidth(4,6); }
.grid_5 { .theWidth(5,8); }
.grid_6 { .theWidth(6,10); }
.grid_7 { .theWidth(7,12); }
.grid_8 { .theWidth(8,14); }
.grid_9 { .theWidth(9,16); }
.grid_10 { .theWidth(10,18); }
.grid_11 { .theWidth(11,20); }
.grid_12 { .theWidth(12,22); }

.column {
	margin: 0 @gutter;
	overflow: hidden;
	float: left;
	display: inline;
}
.row {
	width: @totalWidth;
	margin: 0 auto;
	overflow: hidden;
}
.row .row {
	margin: 0 (@gutter * -1);
	width: auto;
	display: inline-block;
}

We can plug this right into the sample HTML document that comes with the 1Kb Grid to see if everything is working properly.





	
	
	
	

	




12

8

4

4

4

Preview

If you preview this in the browser, it should be working perfectly.

screenshot

Now try adjusting those first two variables in the code to anything you want and check out the result. For instance, we can change the column width to 80 and the gutter to 50 to get a wider content area with less whitespace.

@columnWidth: 80px;
@gutter: 5px;
screenshot

Conclusion

And there you have it, a flexible grid system that can be changed to any width and gutter size by replacing only two values. This merely scratches the surface of the potential here. You can apply these same principles to any and all of your favorite frameworks.

Leave a comment below and let us know how you would change and improve the LESS CSS Grid. Also be sure to let us know if you extend the concept and do something cool with it!

Comments & Discussion

45 Comments

  • drudge

    There are some great insights in this article, but hardly anything that would incite a riot.

    Nice work!

  • honk

    I don’t see any practical use both in this method and in grid systems in general. All I see is a collection of too many DIVs that are actually not necessary to achieve the desired layout.

    And this is the thing: Creating your DIV layout for each project from scratch will take you a few minutes. Make it 30 minutes if it is a complex layout. So why bother with systems like that? It’s probably a fun thing to “develop” something like this but hardly useful in reality.

  • moemar

    Nice, I guess the load time is slightly decreasing and it sure is a nice thing to use custom parameters in the css file.

    But using this method requires that JavaScript is enabled in the browser, which does not make it a perfect solution. But it sure is a nice piece of work!

  • http://www.shiftedwork.de/blog Daniel S

    @hunk: I think the same. I cant realise why css frameworks are that popular.

    For our german readers, i suggest this article: http://www.shiftedwork.de/blog/2010/09/09/uber-den-unsinn-von-css-frameworks/

  • http://www.colddesign.it Giacomo

    Very helpful, thanks!

  • Pedro Augusto

    I did something like this a few weeks ago. I loved it, but your code is much better than mine. I did not know how to use mixin, thanks for showing such a good example!

  • http://www.blackfridaycheaplaptop.us/ bam

    wow thank for your share

  • Joshua Johnson

    Moemar, the JavaScript is only required for utilizing the LESS file. When you compile to CSS and bring the site live, visitors will not need JS enabled.

  • honk

    @Daniel:
    Thanks for your wonderful article. You nailed every single word.

  • http://www.jauhari.net/ Jauhari

    Interesting method, but not all browser accepted JavaScript right?

  • tripdragon

    Eh…. you could have done something different and remove the class grid_xx names from the html and give it to the class style like .name { .gridxx; }

    But as for that. What are the new tricks to remove a container div that can have padding and not screwup the Box model in IE?

  • Pingback: risorse&link | Art&Me()

  • Pingback: Resources and links – 15 October 2010()

  • http://pyperpaul.com/ Jose G.

    Nice article. I love LESS, I’ve been working with it for a little while but I believe that whoever introduces LESS to people should warn them that LESS does not support the following:

    @media {

    }

    For most people it might be fine. But if you start using LESS it means you usually code more complex CSS than average Joe, and not being able to use @media in your .less file is a severe limitation. It’s actually the only reason I do not use as a standard in all my projects.

  • Pingback: Extend your CSS with LESS.app RealerHQ.com productivity blog for creatives()

  • http://incident57.com/less/ Henrik

    If you don’t want to load the JS, simply compile the .less file. LESS.app will automatically recompile the .less into .css any time you make a change to it: http://incident57.com/less/

    I never write anything in plain CSS anymore. If .css is required, it’s just a compilation away.

  • http://www.tripodtravel.co.nz Gordon Anderson

    It ought to be possible to use Compass, the Ruby based CSS framework, to do the maths for you

  • http://incident57.com/less/ Henrik

    Oh, and media queries work fine since version 1.023.

    Just use:
    @media all {

    }

    instead of:

    @media {

    }

    They’re equivalent ^_^

  • Rizky Syazuli

    awesome work! any chance we’ll see a SASS port anytime soon? anyone? :P

  • streetpc

    Like Henrik, I use LESS.app to compile LESS files into CSS, removes the JavaScript issue. I think there are also some libraries that can transform .less files dynamically on server side.

    Another great advantage of less, is that you don’t have to go with the usual downsides of grid systems, like putting the class in your div that explicitly tells what size it is, cluttering your template with information hardly more readable than tables.

    You can go a little further and put only meaningful IDs (or classes) attributes, and inject the CSS layout with LESS. Example:

    #sidebar { .column; .grid_4; }

    I’ve tryied this approach and it really cleanse your templates. The main downside so far is that CSS hacks (like the one for clearfix) won’t work on your ID-applied classes, e.g.
    * html .column {} /*not on #sidebar*/
    and in general you will have to put all information in .column if you want it to be repeated for #sidebar…

  • http://www.joomlasite.nl Joris

    Thanks. I’m going to dive into less and i’m curious if i can use the grid easily myself. Never used grids myself. But its not to late to learn…

  • http://twitter.com/cjsoutham Chris Southam

    I’ve done similar a couple of days ago with the simpler 978px grid here:
    http://pastie.org/pastes/1220748

    I’ll update it to use the mixins though, that’s pretty handy.

  • Daniel Steigerwald

    I have to say I do not see any advantage over plain old CSS percents. This grids uses them e.g. http://github.com/yui/yui3/blob/master/src/cssgrids/css/grids.css

  • Pingback: Less: Reutilizando código en nuestros CSS | TheGuysFromMaia()

  • Pingback: Esoterrific » Blog Archive » Falling in love with {LESS}()

  • http://www.morphealth.com nisa sanjaya

    well. i have used this syntax for my blog.. thanks

  • http://helpjoey.com/ Jose G.

    Re: Henrik

    My mistake, the issue was not with @media it was with @page (v 1.2.21). But it doesn’t lessen LESS CSS :-)

    I just wish there was a way to escape characters so that LESS would skip it, or maybe via comments such as /* =less-ignore:start */ … /* =less-ignore:end */

    Dunno, just rambling.

    Oh and sorry everyone for getting a notification after such a while :-)

  • Matt Thornton

    It is refreshing to see LESS gaining more acceptance, though it still surprises me how few developers have adopted it thus far. I took a stab at a lightweight, semantic, flexible grid system a while back. I’d be interested to hear your thoughts and those of your followers. http://net.tutsplus.com/tutorials/php/how-to-squeeze-the-most-out-of-less/

  • http://cmdtqna.com/ qna

    Maybe it is just me, cause i like using 960 gs..
    But still a nice article!

  • http://nowdirection.com Benxamin

    Mixins make any framework much easier, as this article demonstrates. I’m working on a typography version for our reset.css file.

  • http://jeremyfrank.com/ Jeremy

    Awesome writeup Joshua! Thank you. One tweak that I’ve implemented is to set a variable for the number of columns:

    @columns: 12;

    Then you can use that variable in any width calculations:

    @allColumns: @columnWidth * @columns;
    @allGutters: (@gutter * @columns) * 2;

  • Ruth

    Less looks really interesting – save for the lack of “app” on windows/pc.. shame the Mac app couldn’t be re-created as, say, an adobe air app.

    The grid might also benefit by having an “app” – much like Boks for Blueprint.

  • http://about.me/chrisjacob Chris Jacob

    Excellent write up. I’m working on my own responsive grid system (like http://lessframework.com) and I’m now inspired to build it on top of LESS css ^_^

  • Pingback: My {Less} CSS mixin boilerplate | Blog | pixel perfect front end / interface design and development for web sites, apps & eCommerce stores()

  • http://www.vertstudios.com/ Joseph McCullough

    I hacked together a command line version of Less.app for Windows, allowing Windows users to instantly compile less files on save in production instead of at run time.

  • DMin

    btw, instead of creating your own grid system from scratch, just use an existing framework. I was able to use blueprint in my .less file —
    1) Rename your screen.css to screen.less
    2) Put in the same folder as your style.less and use @import “screen.less”;

    you can now start doing stuff like;

    #header {
    .span-24;
    .last;
    }

    only thing is, I could not get my base div to have a container class. I had to add that as a class into my html — (…) — other than that, it worked perfect. I love css-frameworks and .less — they make things so much more easier.

  • http://shawndellysse.com Shawn Dellysse

    Instead of having to specify @theGutter, it can be expressed in terms of @theColumn:

    .theWidth (@theColumn: 1) {
    width: (@columnWidth * @theColumn) + (@gutter * ((@theColumn – 1) * 2));
    }

  • foljs

    I have to say I do not see any advantage over plain old CSS percents.

    LOL. Percents are of no use in a non-fluid layout. And bitmap resources and graphics make fluid layouts cumbersome and not really ideal.

  • Pingback: out through the winter throat » LessCSS : mon coup de cœur du moment()

  • Callum

    Can I just say – what a great job! A few comments here asking “what is the point” and I felt I should add a few.

    As it stands at the moment it’s a great layout tool – but not particularly easier than 960.gs or Blueprint or doing this old school, however: as a framework where the numbers may be varied by user input – perhaps in a CMS template or (as I have used my own tweaked version) in creating a width-adaptable template (not fluid but genuinely adaptable as in adapt.960.gs) and this way of doing things means I don’t have to do the math for 4/5 different possible page widths, I just plug in a few base numbers and we are good to go.

    Also, it’s just nice to see clever code!

    Good work!

  • http://www.circulationstudio.com Brian

    I have been studying Less and responsive web design and found this article to be a nice glue between the two. I am working on revising our internal boilerplates for a lighter solution than something like Twitter Bootstrap.

    Using this with CodeKit has some serious potential! Thank you.

  • http://www.circulationstudio.com Brian

    Any advice on fluid nesting?

    I am have spend several hours and looked at many existing grid systems, but still I am having trouble rolling my own.

  • http://www.circulationstudio.com Brian

    I created a grid system that handles both fixed and fluid layout “modes”. Thanks for your tutorial is helped me achieve my goals! I detailed my experience and resources used in an article in our news section.

    http://www.circulationstudio.com/news

  • http://www.conradabraham.com Conrad

    Nice. I’ve been tweaking my own framework as well and is nice to compare notes. Lots to takeaway from here.

  • Pingback: 10 Best Responsive HTML5 Frameworks for Web Developers 7th-media()

Subscribe

Membership
About the Author