Added by Chris Planeta

NegativeGrid logo NegativeGrid – fluid CSS grid by Chris Planeta

NegativeGrid is a lightweight, fluid CSS grid based on a technique of negative margins. I originally made it for myself but it turned out to be so good that I’m publishing it here, for everybody to download.

How it is different than other grid systems

Negative grid uses a different approach to positioning columns than ordinary grids. Normally, the position of a column is relative to the column on its left (distance set with a left margin). In NegativeGrid the position of all the elements are calculated from the left border of the container. It is all possible due to a simple margin-right: -100% added to columns. There are many benefits of using this technique.

As you may have learnt Opera has problems with calculating percentages (percentage rounding bug) which can ruin the design and is a big problem with fluid layouts. It is especially visible with many narrow columns in a row. Since the positions of columns in the NegativeGrid don’t depend on the positions of columns next to them the possible differences of elements’ width are minimized.

Also, using this technique lets you change horizontal order of columns only by altering left margins – no need to change the order in html! Although I don’t recommended doing that because of accessibility reasons, it may prove quite useful with slideshows.

How to use it

First of all you should get the code. I don’t like being made to use a fixed number of columns so I made a generator that you can use. If you are not a big fan of additional classes in the markup you can generate the code to use with LESS. In both cases the code is commented so you shouldn’t get lost.

If you generate the ordinary CSS code you will get something like this:

body{width: 100%; max-width:1140px; min-width:60px; margin: 0 auto;}
.col1, .col1p, .col2, .col2p, .col3, .col3p, .col4, .col4p, .col5, .col5p, .col6, .col6p, 
.col7, .col7p, .col8, .col8p, .col9, .col9p, .col10, .col10p {float: left; margin-right: -100%;}

/* Add this class to the container of floated columns */

wrapper_name{overflow:auto; clear:both;} /* clear comes handy in IE */

/* Columns without paddings*/

.col1{width: 8.9%;}
.col2{width: 18.8%;}
.col3{width: 28.7%;}
.col4{width: 38.6%;}
.col5{width: 48.5%;}
.col6{width: 58.4%;}
.col7{width: 68.3%;}
.col8{width: 78.2%;}
.col9{width: 88.1%;}
.col10{width: 98%;} /* Columns with paddings*/ .col1p{width: 6.9%;padding: 0 1%;}
.col2p{width: 16.8%;padding: 0 1%;}
.col3p{width: 26.7%;padding: 0 1%;}
.col4p{width: 36.6%;padding: 0 1%;}
.col5p{width: 46.5%;padding: 0 1%;}
.col6p{width: 56.4%;padding: 0 1%;}
.col7p{width: 66.3%;padding: 0 1%;}
.col8p{width: 76.2%;padding: 0 1%;}
.col9p{width: 86.1%;padding: 0 1%;}
.col10p{width: 96.0%;padding: 0 1%;} /* Horizontal position of columns */ /* By changing classes you can easily change the horizontal order of columns */ .push0{margin-left:1%;}

These classes are self explanatory so I will just concentrate on the most important things.

Columns themselves are made with classes .colX and .colXp (“X” is of course the column number). The former is without paddings and the latter includes them.

Since our columns are floated their containers need overflow set to auto or, alternatively, a clearfix.

You can see these classes in use in the demo. Although the preview below the generated code uses the same dimensions all the style is inline.

Mobile First and LESS

Grid systems are not very “mobile first” friendly, huh? The classes added to the markup make any layout changes practically impossible. A change of one CSS class results in a change of all linked elements. Fortunately, you can go around it with LESS.

Since version 2 the generator can output the code for LESS. By using the given dimensions directly in CSS (with mixins) you make sure that they can be changed in other resolutions. The workflow here might look like this:

  1. Write in your stylesheet all the resolution’s “breaking points” with media queries
  2. Generate different NegativeGrids for each of the resolutions. Don’t forget to change the column and push names (new in v2.1) so they won’t override.
  3. Start styling!

Tips and tricks

As with other CSS grids the use of percentages doesn’t let you nest columns inside other columns. Well, at least not without a bunch of code or unnecessary hassle. Fortunately, in some cases there are ways to get around that. Study the code of this example here to learn how to create false nested columns. Of course this method may not be used everywhere but gives you a bit more freedom

The benefit of using fixed width solutions is that when there is no (horizontal) space for an element it moves below other elements. Since fixed layouts adjust to the width of the screen no such behaviour will be seen. You can, however, enforce it with simple clear: left. It is especially useful in media queries. Try doing it in the demo.

Update: v.1.1 now lets you set the width of page borders. Fixed a small bug in the generator.

Update: v.2 gives you a new generator which outputs the code in both CSS and LESS. Also, it now has an automatic preview of columns and fixes a small bug.

Update: v.2.1. In the generator you can now change class and push names. It is really handy when working with LESS and media queries.

10 discussion entries

    • Chris Planeta

      This is a known bug in Opera browsers connected with improper rounding of percentages. All the other fluid grid systems I’ve checked have problems in Opera. In comparison to them the NegativeGrid however makes these differences much smaller (check e.g. Fluid 960 Grid System in Opera – click “16 column grid”).

      Unlike other solutions where the position of one block depends on the block next to it in the NegativeGrid the position of columns is calculated from the left border of the page (thanks to the use of negative margins, thus the name).

  • Jon

    NegativeGrid worked great for me. Very simple and intuitive. Thank you.

    • Jon

      Actually I’ve run into a problem. Wondering if you have a suggestion. I’ve got some images within the grid and when I attempt to expand them using a lightbox script it won’t work. I’ve been able to determine that body>div{overflow:auto;} is the problem. Any ideas how to resolve?
      Thank you.

    • Chris Planeta

      Ok, it seems that you have not read carefully the last notice in the generator and generated code that was used in the demo (that is where body>div is used) by pressing “Cancel”. In production there should be no thing like body>div. Instead you should add “overflow:auto” to every container wrapping each set of your columns.

  • Thomas

    I checked out your negative grid approach and it works fine for me. I especially like the minimal amount of code.
    I wonder what will be a best practical way of having one long sidebar on the left side, while having many shorter rows of 2, 3 or 4 on the right side.
    Is there an easy, planned way to do this with your system?
    Thanks for your reply in advance.
    Regards, Thomas

    • Chris Planeta

      Hi there Thomas. I’m glad that you liked my system.

      one long sidebar on the left side, while having many shorter rows of 2, 3 or 4 on the right side

      Hmm… I’m not sure what you mean by that. Do you want rows to take space of 2, 3 or 4 columns? How will they be distributed? Give me a link to an image of what you would like to achieve and I will try to help you.

  • Thomas

    Hi Chris,
    I mean just a normal layout with a sidebar, like this:

    Of course, I can work my way to build this with my own floats. I just wanted to be shure before, if I not somehow miss an easy way with the classes you’ve provided.


  • Thomas

    Yeah, that’s damn simple.
    Give the sidebar a class .push0 and omit the .push0 for the rows and use a higher push class instead.
    I like it!
    Thanks for the example and a have a happy new year.