A Simple CSS Grid

R Proffitt
by Richard Proffitt
iopan design

I must admit to having a preference for Simple Solutions to Complex Problems and the complex problem that you keep butting your head against in Responsive Web Design is How to Create Beautiful Layout at All Screen Sizes. Using a CSS Grid framework is the tried and trusted answer, but there are so many different ones out there… — So why not create your own?

The great thing about creating your own bespoke grid system is that it can be tailored exactly to your website's requirements. You can cut out all of the CSS classes that you don't need, chuck away all those extraneous styles that come built-in with so many CSS grid frameworks available. Many grid frameworks are quite bulky with added ‘extras’ and so with a self-build, you can vastly reduce your file-sizes by only building what you need.

Back to Basics

The CSS Grid Framework shown in this article is a comfortably basic affair. No complicated arithmatic and no complex styling. By adding a few media queries it can become a very useful, basic, tiny, responsive layout grid.

box sizing diagram
Even the Playing Field

First thing's first, set the CSS box-sizing property to border-box.

By default, the width and height of an element is calculated thus:

  • width + padding + border = actual width of an element
  • height + padding + border = actual height of an element

Before CSS3's box-sizing property came in to use, webdesigners would have to remember to calculate out the padding and border to get the actual width and height of the element as it was to be seen; the element often appeared bigger than you had set it since the padding & border were being added. This created a lot more work (and a little confusion) when planning layout, so box-sizing was something of a blessing.

With the property set to box-sizing:border-box the padding and border's are taken out of the calculation of the actual width & height — a much more common-sense approch I think. It also makes the overall planning of a layout easier to grasp. Use the following code to set border-box on EVERYTHING.

*, *:after, *:before {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;

Reset & Zero Everything

One of the first actions that I take on just about any CSS project is to make sure that we start off with a clean slate; by this I mean that all CSS properties are re-set to a neutral state. This is necessary since different browsers have slightly different default settings for some HTML tags. You could use Eric Meyer's famous reset snippet, or there are others such as normalize.css etc.

I'm using Eric Meyer's most recent reset, it is available on his website at: http://meyerweb.com/ and you can also see the code below:

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
body {
	line-height: 1;
ol, ul {
	list-style: none;
blockquote, q {
	quotes: none;
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;

/* remember to define visible focus styles! 
:focus {
	outline: ?????;
} */

/* remember to highlight inserts somehow! */
ins {
	text-decoration: none;
del {
	text-decoration: line-through;

table {
	border-collapse: collapse;
	border-spacing: 0;

The Grid's Columns

A twelve column grid is something of a convention, so I'll be guided by it here and create twelve equal columns. We need to express everything in percentages to make it responsive, this means that 1 column as a fraction is 1/12 and as a percentage can be expressed as 8.33333333%.

The table below shows the other numbers of columns with their percentages calculated and rounded off.


We'll prefix the column's class name with col- so that we can refer to them as col-1… col-2… col-3… and so on. In order to have the columns sit next to each other we need to float them left and state their width. We can float them all left with the following code:

[class*='col-'] {
  float: left;

The widths, we have to input individually:

.col-12 {
    width: 100%}
.col-11 {
    width: 91.66666667%}
.col-10 {
    width: 83.33333333%}
.col-9 {
    width: 75%}
.col-8 {
    width: 66.66666667%}
.col-7 {
    width: 58.33333333%}
.col-6 {
    width: 50%}
.col-5 {
    width: 41.66666667%}
.col-4 {
    width: 33.33333333%}
.col-3 {
    width: 25%}
.col-2 {
    width: 16.66666667%}
.col-1 {
    width: 8.33333333%}


We are going to contain the columns inside a class called row and it is necessary to clear the row which is the parent element, otherwise the height will collapse to zero. so we can clear the row with the following code:

.row:after {
  content: "";
  display: table;
  clear: both;

The Gutters

Gutters are reasonably straightforward. I'm going to add a margin (in pixels) to the right hand side of each column, and then remove the final margin using the psudo-class :last-of-type

. Here's the code:
[class*='col-'] {
  margin-right: 18px;
[class*='col-']:last-of-type {
  margin-right: 0;

Finally, I'll use the class .grid as a container, and make it 100% wide:

.grid {
     width: 100%;

Take a look at the demo page and if you wish, download the files. The next challenge is to make the grid fully responsive by adding media queries which will change the way in which columns fit the page. I'll leave you with a ‘fix-all’ solution for viewing on devices which are 360px or less.