Flexible Responsive CSS Grids

Posted Wednesday 28th March, 2012

There are many ways to build CSS column grids; all of which have their pros and cons. In fact CSS3 has begun to implement a built-in model for columns which will be most useful in the future. However, until all the browsers our users surf the interwebs with are capable of this, we’ll have to rely on the good old CSS2 tricks to do it.

For a good while I used defined width floats for my grids. This means you have to calculate the width of each column and fix it (either with pixels or something more flexible like ems or percentages). That method is flawed due to rounding errors and general problems with flow when resizing. A better method is to use a mix of floats and negative margins for positioning. When I need to create a CSS column grid, I use this method.

However, when I was recently asked to share my method—which was outlined to me by a good friend and CSS guru—I had to remind myself how to do it. These are the perils of becoming a manager and developing less. In the interests of remembering next time (and also sharing the knowledge), I’ve decided to document the method in this article.

A word on frameworks

Just a quick word really. There are frameworks out there that will do your grids for you. I know they exist but I do not use them. Often they result in bloated mark-up and esoteric element identifiers that create unmaintainable code. Your mileage, of course, may vary.

I’m capable of creating a grid with the minimum possible code required. Hence, for production purposes, that’s what I do. In a prototyping situation, when I need something quickly and painlessly, I may choose to favour a framework; but it hasn’t happened yet.

If you choose to use a framework to set-up your grid, this article probably isn’t for you.

Source order is important

It’s good to make sure your main content is first in your source order. It’s helpful for accessibility, and it’s (a bit) helpful for SEO. This is something that isn’t always easy to enforce when using traditional grid techniques. The technique I use is actually built around this concept.

Building the mark-up

The simplest possible mark-up we would want for a three column layout would be something like this:

    Main content
    Secondary content

To make it a little easier to target, and to make it a bit more readable, we can add some element identifiers:

<div class="main container">
    Main content
<div class="related container">
    Secondary content
<div class="navigation container">

This gives us three containers for our columns. If we were to use the simplest possible method of floating each column left and fixing their widths, we’d have ourselves a column grid. However, that grid would not respond reliably cross-browser and could pick up wrapping errors. It also requires exact knowledge of the required width of ALL columns. Depending on how we’d like our grid to respond to change, this may be suboptimal.


A floated element is shifted to either the left or right of its containing box and surrounding content then flows around it. Floating multiple boxes stacks them up either left or right, which is useful behaviour when attempting to simulate columns. However, if there is not enough horizontal room for the float, it is shifted downward until either it fits or there are no more floats present.

Floats are taken out of the normal flow of the document. This means the positioning model is changed somewhat and we can use that to our advantage.

The trick

Applying a negative margin to a floated element allows us to control how it makes use of empty space around it. We can make use of this if we add an extra wrapper to our main content:

<div class="container">
    <div class="main">
        Main content
<div class="related container">
    Secondary content
<div class="navigation container">

To make two satellite floats react correctly we need to make sure that our newly added container is also taken out of the normal flow of the document with a float. However, we don’t want surrounding content to flow around it so we should fix its width to 100%.

.container {
    float: left;
    width: 100%;

Next we want to put some space around our main content using standard margins:

.main {
    margin-left: 150px;
    margin-right: 200px;

Now let’s fix the width of those satellite columns:

.navigation {
    width: 150px;
.related {
    width: 200px;

This will result in our three containers floating alongside each other. However, because the first container is set to a width of 100%, the two satellites drop down beneath it.

We want the satellites to take up that nice clear space we’ve created with the normal margins on our main content within the first container. To do that, we shift them left across the first container using negative margins:

.navigation {
    width: 150px;
    margin-left: -100%;
.related {
    width: 200px;
    margin-left: -200px;

Here we’ve shifted the navigation container 100% across the width of the container of our floats (in this case, the body of our page). This puts it flush to the left, filling the space to the left of our first floated container.

We then shift the related container only 200px to the left, matching its width and therefore leaving it flush to the right of the first floated container.

This leaves us with a perfect three-column grid. What’s more, since we’re only fixed the width of our satellites and have left the main content in normal flow, it will respond to the width of its container, as will the position of the satellite floats.

Demo and source

I’ve taken the above and scrubbed it up a bit, to create a nice flexible responsive CSS grid demo page. Further to that, I’ve also stuck the code up on GitHub in a “flexible CSS grid” repo. Feel free to do with it as you wish.

Included in: CSS, Development, HTML, Reference, Web


  1. Accessibility
  2. Agile
  3. Ajax
  4. Apache
  5. API
  6. Architecture
  7. Books
  8. Browsers
  9. CMS
  10. CouchDB
  11. CSS
  12. Design
  13. Development
  14. Django
  15. Email
  16. Events
  17. Gaming
  18. Grammar
  19. Hardware
  20. HTML
  21. HTTP
  22. Humour
  23. Idea
  24. Information Architecture
  25. JavaScript
  26. jQuery
  27. Lean
  28. Life
  29. Linux
  30. Literature
  31. Mac OS X
  32. Management
  33. Meme
  34. Microformats
  35. Monday
  36. MySQL
  37. Networking
  38. News
  39. Personal
  40. Photoshop
  41. PHP
  42. Process
  43. Python
  44. Reference
  45. REST
  46. Science
  47. SEO
  48. Server
  49. Site
  50. Sitepimp
  51. Social
  52. Spelling
  53. Syndication
  54. Testing
  55. The Future
  56. Thoughts
  57. Tools
  58. Tutorial
  59. Tutorials
  60. Typography
  61. UI
  62. UNIX
  63. Virtualisation
  64. Web
  65. Web Standards
  66. Widgets
  67. Wii
  68. Writing
  69. Xbox
  70. XHTML