Read my book

I wrote books about Webpack and React. Check them out!

Sunday, September 8, 2013

Build Your Own CSS Grid System

I know there are a lot of premade CSS grid systems out there. Foundation, the CSS framework, comes with likely my favorite implementation. It allows you to define how the grid behaves in different scenarios using a class syntax such as this: small-5 big-3 columns. Very simple yet powerful. It is possible to nest the grid infinitely and it comes with offsets and other goodies.

Sometimes it can be convenient to be able to implement something like this on your own. At least it is a good learning experience. In an ideal world we would be able to use flexboxes but that is still years away. So for now we are stuck with custom solutions.

I've tried to keep my implementation somewhat minimal. It uses a clearfix hack by Nicolas Gallagher. The semantics are similar to Foundation. There are rows which in turn may contain columns. You can nest rows within columns. My implementation is missing offsets and such and I'll leave implementing those as an exercise to the reader.

The basic CSS to make it all work looks like this:
/* http://nicolasgallagher.com/micro-clearfix-hack/ */
.row:before, .row:after {
  content: " ";
  display: table;
}

.row:after {
  clear: both;
}

.column {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;

  display: table-cell;
  vertical-align: top;
}

@media (max-width: 768px) {
  .small-1 {width: 8.333%;}
  .small-2 {width: 16.666%;}
  .small-3 {width: 25%;}
  .small-4 {width: 33.333%;}
  .small-5 {width: 41.666%;}
  .small-6 {width: 50%;}
  .small-7 {width: 58.333%;}
  .small-8 {width: 66.666%}
  .small-9 {width: 75%;}
  .small-10 {width: 83.333%}
  .small-11 {width: 91.666%;}
  .small-12 {width: 100%}
}

@media (min-width: 768px) {
  .large-1 {width: 8.333%;}
  .large-2 {width: 16.666%;}
  .large-3 {width: 25%;}
  .large-4 {width: 33.333%;}
  .large-5 {width: 41.666%;}
  .large-6 {width: 50%;}
  .large-7 {width: 58.333%;}
  .large-8 {width: 66.666%}
  .large-9 {width: 75%;}
  .large-10 {width: 83.333%}
  .large-11 {width: 91.666%;}
  .large-12 {width: 100%}
}
Just that clearfix, border-box and some column width declarations make it work! The nice thing about border-box is that it makes padding work intuitively. In other words you may apply padding to columns without breaking the entire layout. This won't work in ancient browsers but otherwise it is a well supported feature well worth using.

As you might want to see the system in action, consider the example below:

JS Bin

I hope this little example works as a starting point for your system. If you use a preprocessor, you can likely eliminate some of the code above and make the system dynamic. There is also room for new functionality. Happy hacking!