Grow your CSS skills. Land your dream job.

Don’t Overthink It Grids

Published by Chris Coyier

The vast majority of websites out there use a grid. They may not explicitly have a grid system in place, but if they have a "main content area" floated to the left a "sidebar" floated to the right, it's a simple grid.

If a more complex layout presents itself, people often reach for a grid framework. They assume grids are these super difficult things best left to super CSS nerds. That idea is perpetuated by the fact that a lot of the grid systems they reach for are very complicated.

Here's how I build grids. It's not hard or complicated. Even making them flexible is no big deal.

Context

A block level element is as wide as the parent it's inside (width: auto;). We can think of it as 100% wide. The wrapper for a grid probably don't have much to do with semantics, it's just a generic wrapper, so a div is fine.

<div class="grid">
  <!-- 100% wide -->
</div>

Columns

Let's start with a practical and common need: a main content area being 2/3 the width and a sidebar being 1/3 the width. We just make two column divs with appropriate class names.

<div class="grid">
  <div class="col-2-3">
     Main Content
  </div>
  <div class="col-1-3">
     Sidebar
  </div>
</div>

To make them next to each other, we just need to float them and apply widths. We can select both like this:

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

and individual width like this:

.col-2-3 {
  width: 66.66%;
}
.col-1-3 {
  width: 33.33%;
}

That's the whole premise of not overthinking grids.

Clearing Context

The parent element will collapse to zero height since it has only floated children. Let's fix that by clearing it. These days all you need is this:

.grid:after {
  content: "";
  display: table;
  clear: both;
}

Gutters

The hardest part about grids is gutters. So far we've made our grid flexible by using percentages for widths. We could make the math all complicated and use percentages for gutters as well, but personally I don't like percentage gutters anyway, I like fixed pixel size gutters. Plus, we're trying to keep too much thinking out of this.

The first step toward this is using box-sizing: border-box;. I like using it on absolutely everything.

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

Now when we set a width, that element stays that width, despite padding or borders being applied.

The second step is applying a fixed padding to the right side of all columns except the last one.

[class*='col-'] {
  padding-right: 20px;
}
[class*='col-']:last-of-type {
  padding-right: 0;
}

That's all there is to basic gutters.

Outside Gutters

Need gutters on the outside? I like using an opt-in class for this:

<div class="grid grid-pad">
  Grid with outside gutters also
</div>

Step one is to add left padding to the grid parent (and optionally top and bottom padding):

.grid-pad {
  padding: 20px 0 20px 20px;
}

Step two is to restore the right padding to the last column:

.grid-pad > [class*='col-']:last-of-type {
  padding-right: 20px;
}

More Column Choices

Super easy:

.col-1-2 {
  width: 50%;
}
.col-1-4 {
  width: 25%;
}
.col-1-8 {
  width: 12.5%;
}

Do whatever you want. Just make sure the column fractions add up to 1. Yeah, a little thinking, but easier than usual.

Sass

I'm not using it heavily here, but the whole bit becomes even a bit more succinct with SCSS/Compass:

* {
  @include box-sizing(border-box);
}

$pad: 20px;

.grid {
  background: white;
  margin: 0 0 $pad 0;
  
  &:after {
    /* Or @extend clearfix */
    content: "";
    display: table;
    clear: both;
  }
}

[class*='col-'] {
  float: left;
  padding-right: $pad;
  .grid &:last-of-type {
    padding-right: 0;
  }
}
.col-2-3 {
  width: 66.66%;
}
.col-1-3 {
  width: 33.33%;
}
.col-1-2 {
  width: 50%;
}
.col-1-4 {
  width: 25%;
}
.col-1-8 {
  width: 12.5%;
}

/* Opt-in outside padding */
.grid-pad {
  padding: $pad 0 $pad $pad;
  [class*='col-']:last-of-type {
    padding-right: $pad;
  }
}

Modules

I like to work within these grids with "modules".

<div class="grid">
  <div class="col-2-3">
     <article class="module">
        stuff
     </article>
     <article class="module">
        stuff
     </article>
  </div>
  <div class="col-1-3">
    <aside class="module">
       Sidebar stuff. Sub modules?
    </aside>
  </div>
</div>

It feels nice breaking up content into bits this way. The bonus side effect being that each module can have padding of it's own, keeping text away from the edges of the grid.

Result

Here's a demo on CodePen.

Browser Whatnot

Works just great in IE 8 and up and all the other standard stuff. If you need IE 7 support, you'll have to do something else =).

Also, Flexbox is going to make this even easier and better (in various ways, including reordering on demand), but I think we need about a year until we can start to think about using it.

Related

Check out OOCSS grids.

Comments

  1. Hey Chris this is cool!! thanks I am going to give it a try
    Donna Phillips

  2. arf_root
    Permalink to comment#

    What I wonder about this example, and a lot of the grid frameworks, is the side effects of the naming scheme. In this example you have a bunch of class names that effectively have the presentation encoded into their names (col-1-3, col-2-3, etc). What happens when you have to create a new stylesheet for a user agent with a much narrower screen? Now you have class names that make no semantic sense… ‘col-1-3′ might be 100% width.

    Class naming is always a constant battle for me. When I try going ivory tower, pure semantic names I end up with a bunch of classes/ids that are so generic the stylesheet is impossible to interpret.

    • Which is a classic use case of @extend =)

    • @Chris Exactly!

      I have no problems shoving non-semantic class names into my markup but if you itchy about that just extend your semantic class/id to the grid class in sass.

      header{
      padding:1em 0;
      @extend .col-3-3;
      }
      
    • AntoxaGray
      Permalink to comment#

      I never been confused that all grid classes on mobile have 100% width. Well… because they are all 100%?

    • Uhm, hello! First I’ve seen @extend with SASS…. where have I been?! Going to deploy now! Thanks!

    • Eelco
      Permalink to comment#

      Problem with @extend here is that it won’t use “[class*='col-']“. So you’ll be missing your “float: left;”. Just a quick heads up.

    • Kevin
      Permalink to comment#

      Wouldn’t the new %placeholder syntax have great use here to not include the column classmates in your code but continue utilize them to ensure you’re adhering to your grid (assuming you don’t need to dynamically create columns for the purposes of the site you’re using the grid for, though you can still use the classnames and just create the equivalent %placeholder) to lower the number of selectors you use on your stylesheet significantly?

  3. Permalink to comment#

    Grid systems that depend on specific (and often overly verbose) HTML drive me nuts. I am pretty hardcore in the belief that all class names should be reflective of the type of data they contain and that any layout driven code should strictly remain within the CSS file. However, HTML grid systems completely undermine this and in a way remind me of the days back when we used tables for layout.

    • Permalink to comment#

      I’m kind of newbie with this stuff, but the problem I see is that presentation and content really aren’t 100% separable. What if I display same types of content differently on different pages? Now I’ve got to define more selectors in the stylesheet for per-page cases. Whereas, if I’m just doing a unique page and I want to arrange content in a certain way, I can use specific grid classes to do so right in the markup without having to go pick apart a stylesheet. If you try to 100% abstract presentation from content, what you’re targeting is only a subset of use cases. There’s no single solution for every design problem.

  4. Donald Allen
    Permalink to comment#

    Is using *:after, *:before required? I’ve always used just *.

  5. jochem
    Permalink to comment#

    Most grid systems arent any morercomplicated then this. Whats the difference between div-1-3 / div-2-3 and span4 / span8 ? Basicly its the same. Except perhaps the pixel based gutter.its just that most grid systems are merely a smaller part of a larger css framework. But ive often just selected the items i needed and discarded everything else. The end effect is the same though.
    I’m curious though. I see a lot of people adding a similar clearfix to their css. Why ?Almost everytime adding overflow hidden to the parent gets the same result without adding extra content we dont need.

    • Permalink to comment#

      I wish someone had replied to jochem’s question. I was wondering the exact same thing. Any help?

    • Permalink to comment#

      adding overflow: hidden is a very easy and good way. but if you have some contents that need to be displayed in an overlapping way and are markupped in the same box (e.g. small layers/tooltips or validationbubbles), then you can’t use overflow: hidden.

      cheers

  6. Permalink to comment#

    Great work, once again.. I’m an advocate of using grids in a ‘sensible way’ (eg. not just throwing a grid under a design for the sake of saying you’ve used one!) And this, is a great way to implement a light (code-wise), efficient grid,. dig the border-box method as well.
    Great work!

  7. Matthias
    Permalink to comment#

    I love the idea behind grids (regular layout), and use it for wireframes and mockups. But I hate the grid frameworks, because they fill a lot of semanticless html into my code.

    And I dislike flexible grids, too. A lot of webdesigners neglect one major fact (no offense, Chris): That readability (an important part of the user experience) drop if you have too small or too wide text length per line.

    • Marie
      Permalink to comment#

      Though, that’s not really the fault of the grids, is it? I completelly agree with your assessment that the text length/line shouldn’t be too short or too long, but my feelings on it is that ensuring that there is a good medium is to add more breakpoints/etc in any media queries. For example, I have a fairly standard content – sidebar layout, where once the screen gets large enough, the two get higher margins, and a few steps after, the content gets extra padding.

      This, obviously, still means that the text length isn’t consistent, but the strength and weakness of the web are the same: You can never tell what someone else is using, nor why.

      (and on a sidenote, I really like the reply/comment layout. Clean, attractive, interesting)

  8. verpixelt
    Permalink to comment#

    Thanks for the post Chris. I like the simplicity in your grid. And n1 tipp with the *selector and the pseudo-elements(:before & :after).

  9. mp
    Permalink to comment#

    Is this grid system really IE8 and up with all the “last-of-type” selectors used? Am really just wondering since it looks great but not sure how that’ll work?

    • Sinled
      Permalink to comment#

      unfortunately only ie9 and up
      just checked – “last-of-type” not working in ie8

    • MaxArt
      Permalink to comment#

      In fact, that doesn’t work in IE8. But IE8 does support :first-child, so you can change the CSS to use it:

      [class*='col-'] {
          padding-left: 20px;
      }
      [class*='col-']:first-child {
          padding-left: 0;
      }

      Of course, you can’t have other types of elements before the first column.

    • Permalink to comment#

      This was my question too. Wish they’d update the article content to reflect the fact that the “last-of-type” styling won’t work in IE8, in case people implement this grid system without vigilant fact-checking.

  10. When I first read “Transcending CSS” by Andy Clarke the biggest thing I took away was the idea that in order to work across multiple browsers using a columnar layout (even IE7) you must contain your content within the container and give padding to the content inside – keeping the actual container unadulterated. Of course it’s more markup using extra divs.

    
    <div class="container row-all">
    <div class="container float-container>
    
    <div class="container row-3-4">
    <section class="main padin">blah blah blah</section>
    </div>
    
    <div class="container row-1-4">
    <section class="complementary padin">more blah blah blah</section>
    </div>
    
    </div>
    </div>
    

    I agree the layout structure is easy peezy, but we still need columns to help with tight alignments. I mean… sure you have this wonderful proportional laid out box, but how do you line the content up within it? Where are the guides? This is where I think Gridset is making leaps and bounds by helping us keep our layout nice and straight.

  11. John
    Permalink to comment#

    why not add the padding to all sides? I’m I missing something with the whole [class*='col-']:last-of-type add on.

    • John
      Permalink to comment#

      *am I

    • If you add padding all the way around on the parent .grid, the last column will be incorrect. The technique in the article keeps them all equal.

    • Tom Potts
      Permalink to comment#

      I was thinking this myself. Chris, if you go the the CodePen Demo you can see the difference: copy in the following:

      /* Opt-in outside padding: v2 */
      .grid-pad2 {
        padding: $pad;
      }

      and then change one of the padded grids to use grid-pad2; as you add and delete the “2”, you can see the difference in spacing. It’s not really clear which is “best” on the thirds example, but it’s obvious it’s gone wrong on the eighths example.

      The trouble is, both methods look horrible if you try to use a different outside padding. You can see this at this version on CodePen.

      I tried for a while to think of a better way that handles all of these cases, but I couldn’t quite figure it out. I think the real answer is: wait for flexbox! *grin*

  12. Permalink to comment#

    yes…its more realistic when we built out grids suited to our design rather than design on a grid.

  13. Rune
    Permalink to comment#

    I knew absolutely nothing about grids. thanks!

  14. Jhon
    Permalink to comment#

    I love the grid Chris I have been using Bootstrap one for a long time, plus I use these kind of abtractions on modules too, one thing I still can’t find a solution when using grids is when I’m creating a responsive site and in the design I have to fix a breakpoint, an error in that ocurr in the design at a certain width, but these grid classes are used acrossed the whole page , so If I target one of these classes to fix the problem that fix is gonna affect all other instances of that class ruining the layout, so I have been forced to fix these error using parent based classes, using maybe the especific body class for the page or a parent of the grid where that problem happened, any ideas on this?

  15. Johan
    Permalink to comment#

    I have tried a bunch of frameworks, and currently are quite happy with semantic.gs. Because I can keep the names I the CSS. I use it on the job for big multinational sites. It comes is less, sass and Is very compact and clever made

    • I totally agree. semantic.gs seems to be the best grid system so far.

      – Responsive
      – Semantic
      – HTML bloat free
      – Built on LESS / SASS

      What does Chris Coyier think about that idéa? No HTML bloat!

    • Permalink to comment#

      I’d like to see examples of website made with semantic.gs …
      With css (for the grid) applied to header, article, section, aside, footer you can use them only once (?)

      I can see some *simple* layouts but, after reading the css of the home page of semantic.gs ( http://semantic.gs/stylesheets/screen.css ) :

      section#overview
      article#documentation ul#examples li
      nav div#download

      css based on ids ?

      Like Atimoda said, you can keep your HTML semantic

      change Chris example to :

      
      
          <article class="col-2-3">
                   Main Content
            </article>
              <aside class="col-1-3">
                   Sidebar
          </aside>
      
      

      and your HTML is “semantic”.

    • You can choose the elements you want and that way the HTML code is clean.

      Look at this HTML code:

      Nested

      You set it up like this:

      article {
      .column(9);
      }
      section {
      .column(3);
      }
  16. Jenny Craig
    Permalink to comment#

    Hello! I’ve read your article. It was really helpful & informative. I’ll visit your blog again to get new update..

  17. GreLI
    Permalink to comment#

    It’s nice, but problem arises when you need, say 20% but no less then 200 pixels. Then the other column have to take place left after that column.

  18. I think the name of the grid is not very good. If we use grid we have to use additional big css file, why we cant custom the grid?

  19. Dave^
    Permalink to comment#

    This is a really explanation Chris. I did have just a couple of quick questions:

    Why use display:table rather than display:block when you’re clearing? I always use display:block, so just wondering if there is an advantage (or drawback) I’m missing out on.

    Secondly, when you restore the right hand padding, why not just remove the rule that removed it? Or were you keeping both rules in there so that you can optionally use grid-pad when you want padding, and not use it when you don’t? (Having typed this question out, I think I’ve already answered it – but hey, worth confirming).

    A superbly written article nonetheless – thanks!

  20. Ian Rock
    Permalink to comment#

    I agree with the above comments about keeping it semantic and using preprocessors for grids.

    Even just amending the layout of a 10 page static site can be a right PITA when you have hard-coded the layout into the HTML… possibly just me though as I get a psychotic twitch every time I see anti-semanticism! ;o)

    I’ve been using Susy responsive grids. Johan’s semantic.gs suggestion looks good (cheers), gonna have a play today. :)

  21. Is there any disadvantage to using negative margins on the grid and leaving the padding on both the left and right of every column? E.g. The grid container has a margin left and right of -10px and the columns use padding left and right of 10px. Than you could just remove the negative margins when you want padding on the grid.

  22. Hi Chris,

    Thanks for a great post. I have been playing about with your code and just wondered if you had considered nesting grids with this as it is something I think will be very usefull. I added this to fix an issue I found with it:

    .grid-pad {
        padding: $pad 0 $pad $pad;
        [class*='col-']:last-of-type {
            padding-right: $pad;
        }
        .grid [class*='col-']:last-of-type {
            padding-right: 0;
        }
    }

    I also noticed that if you do not use the .grid-pad on every row you will end up with the last div being slightly larger than the rest of them due to the removed padding not being distributed equally between all the other divs.

    Do you have any idea how to rectify this?

    Cheers

    Paul

    • Permalink to comment#

      I knew someone else would catch the issue. ;-) In case Paul’s fix wasn’t clear, the original has padding-right 0 as the default, whereas padding on all sides should be the default.

      The original therefore has the opposite of what’s intended: the last element of type HAS padding-right. Paul’s fix shows that on the last of type, padding-right should be zero.

  23. cln lgr
    Permalink to comment#

    I started reading up on grids and downloaded a few but never understood why I would need a grid system that had more stripes than my boxers. (sorry for the mental picture)
    This makes more sense to me, it could easily be upgraded by adding a 1-1-1-4 at 24% if needed or whatever.

  24. Roma Serebryakov
    Permalink to comment#

    Great job! Very useful information, is SASS you tool of choice for optimizing your CSS? Thanks

  25. Great post Chris. I think making a grid that works for YOU is the most important thing. Why use a 12-24 col grid when you just use three columns?

    I am working on a Sass/Compass grid system that supports asymmetric grids. This allows for complex stuff, but most people just need two or three columns and with webkit rounding errors uniform 24 column grids can get pretty bad. It’s often better to use a lower resolution asymmetric grid that suits your needs. $columns: 70%, 10%, 20%;

  26. Permalink to comment#

    The only problem when you use background color for your blocks and the content of the columns differ.
    Example: http://codepen.io/anon/pen/ruFGc
    Why are you using floating blocks when you can use table elements without any clearing fix? All the major browsers are supporting it (IE 8+ support it but I think it’s more than enough).

  27. Nice one, Chris. As a Python developer, and a female for that matter, it really blows me away to see how web developers and designers work effortlessly with CSS. I tried dabbling into web design during my holiday but I was hopeless at it.

    Great job BTW :)

  28. Permalink to comment#

    Succinct and savvy.

    I’m just bouncing the code and conventions in this post into the
    concrete5 html5 Boilerplate template. Slotting in really well.

    Thanks for stripping out grid theory to demonstrate the foundations in a way that my brain can comprehend.

    Love css-tricks and ShopTalk

  29. Varun
    Permalink to comment#

    Thanks! nice post.

  30. Permalink to comment#

    Dear CSS-Tricks,

    I want to have your babies. And I don’t even like kids. And, I’m a boy.

    You rule,
    twrecks

  31. you should give Susy a shot, it’s a grid ssytem for Sass/Compass, no need for extra markup

  32. Permalink to comment#

    Interesting timing, I was just dreaming up a nice flexible grid system for a project at work. I also chose to use box-sizing: border-box;, percentage widths, and padding as gutters.

    One thing to note:

    Converting the padding from right…

    
    [class*='col-'] {
      padding-right: 20px;
    }
    [class*='col-']:last-of-type {
      padding-right: 0;
    }
    

    to left, in conjunction with :first-child

    
    [class*='col-'] {
      padding-left: 20px;
    }
    .grid [class*='col-']:first-child {
      padding-left: 0;
    }
    

    plus a box-sizing polyfill should get you browser support in ie7 with the same techniques. (haven’t tested, so I may be missing something else that fails support.)

  33. Permalink to comment#

    Superb… :)
    Can you please give us any example which is work in IE7 also.

  34. Is there a clothing line available for codepen? Are there any silver stars available? What’s the difference between loud and soft?

    Do it Roosevelt!!!

  35. Really enjoyed this post; learned some new things and have even tried using it on a project.

    My only problem is how would I manage to make an entire “.module” change from a div to a link and still retain the width. When I try this with both an image and text, the padding of the module wraps to the side of the text/image.

    Here’s an excerpt of what I’m trying to achieve: http://codepen.io/anon/pen/qfcJw

    Any help would be appreciated and thanks for the article Chris.

  36. Casey Dennison
    Permalink to comment#

    Chris, your a freaking genius :) Although, a lot of this is like a foriegn language to me.

    I’m glad you posted this, as I have been trying to wrap my head around grids for awhile now.

    As for clearing floats, what’s the difference between display: block; and display: table;?

    Casey.

  37. Interesting, but “Works just great in IE 8 and up and all the other standard stuff. If you need IE 7 support, you’ll have to do something else =). ” makes it harder already ;) great with all new browsers of course. But I guess that’s why using a fully functioning grid system is so great: we can use it for older browsers as well (except for the really really ancient dinosaur ones, obviously ;) )

  38. Nice work Chris. I enjoyed reading and learning it.

  39. Tiste
    Permalink to comment#

    Hi,

    There is something I don’t understand. If I want two columns with the same width, i have to use this:

    
      <div class="col-1-2"></div>
      <div class="col-1-2"></div>
    

    But if I use gutters, my first <div> will have a “padding-right:20px”. So, the width of my first box won’t be “50%” but “50% – 20px”. So in reality, my two columns won’t have exactly the same width.

    I’m wrong?

    • Box-sizing ensures that the width is the same, regardless of padding.

    • Tiste
      Permalink to comment#

      Yes but no. My two will take the same space, but the content width of the first box will be smaller than the content width of the of the second box. Example:

      
      <div class="col-1-2">
          <p></p>
      </div>
      <div class="col-1-2">
          <p></p>
      </div>
      

      Here, my twos won’t have the same width, while the two columns are assumed to have the same width.

    • This works and makes the columns equal. Doesn’t rely on :last-of-type either which I think is more preferable

      .grid {
              overflow: hidden;
              margin-left: -20px; /* same as your gutter */
      }
      [class*="col-"] {
              padding-left: 20px;
      }

      I wouldn’t use an attribute selector per column personally, would just add a class of .grid-col.

      More on this solution

  40. I’ve found that using “last”-type selectors means taking a performance hit in browser rendering. It’s far faster for the browser to “find first-of’s”. So I’d change the above code to:

    [class*='col-'] {
      padding-left: 20px;
    }
    [class*='col-']:first-of-type {
      padding-left: 0;
    }
    
  41. Thanks for publishing this technique. The border-box seems to be the key in making this simply work.

  42. Yeah, separating the grid and modular content is the way to go. I’ll risk preaching to the crowd and tell you why I like it so much:

    1. It just feels right.

    2. If you need to move a module to another place column, it’s as easy as pick up and drop. You don’t have to change any grid classes to adjust it to its new home.

    3. I like to add margin-bottom to all my HTML5 semantic context-creating elements (section, article, nav, aside), such as margin-bottom: 30px. This guarantees that those areas that supposed to be separated logically are also separated visually. I then use some utility classes to add or decrease the margin on modules that might need it. Since the margin is applied to all the HTML5 context-creating elements, I simply choose the appropriate one of the module (most often section), and I know spacing will look good. So, as I build my site, I don’t have to worry about margins too much. I just layout my grid, start adding modules, and everything is spaced out nice and automatically.

    Example:

    .page section,
    .page article,
    .page aside,
    .page nav         { margin-bottom: 30px; }

    4. I also like to add this big of code to make spacing even tighter and more consistant.

    .page section > :last-child,
    .page aside > :last-child,
    .page article  > :last-child,
    .page nav > :last-child      { margin-bottom: 0; }

    This makes sure that the last element in a module has no margin bottom. This way the last element inside a module doesn’t add to the distance between two modules that are stacked inside of a grid column. Their distance is purely decided by he margin-bottom of the module HTML5 element. This also help f you add a background and padding to the module, because it removes that extra space towards the bottom and creates even spacing all the way around.

    That’s why I like separating grid and modules. Makes it easy to move modules around and space things out vertically. Just thought I’d share. Any comments or suggestions about this approach?

  43. That’s exactly how grids are done. Don’t know, why people always rely on complicated grid systems.

  44. @Christian Krammer, people like complicated grid systems because they like to make things seem harder than they really need to be. Guess it’s an ego thing :)

  45. Jason
    Permalink to comment#

    Nice post! Too bad it’s all fluid, which there was a 2 col Fluid-Fixed example too.

    Regards J

  46. Great Post! I was fearful of jumping into Grids but you cleared the air a bit. Thanks!

  47. Great techniques in use here, and it’s certainly quite easy and often preferable to roll-your-own grids.

    I created something to help me along these lines recently in my Proportional Grids framework, which uses negative margin on the grid wrapper instead of :last-of-type to eliminate the gutter issue.

    It uses fixed gutters as well (Chris, they make sense!) and proportions to build up grids quickly using classes alone, specific to each breakpoint.

    Check it out anyway, someone may find it useful :)
    http://builtbyboon.com/blog/proportional-grids

    • Permalink to comment#

      Outstanding article and really appreciated the resourceful feedback from everyone.

      Matt, your layout and menus are soooooooooo practical.
      Thanks for sharing.

      I used Chris’s responsive menu on my site and I sure wish it was possible to style the select menu with better color choices.

  48. I noticed the same thing Tiste did earlier on in this discussion. In this example:

     
    <div class="col-1-2">
         <p> </p>
     </div>
     <div class="col-1-2">
         <p> </p>
     </div>
    

    the 1st paragraph and 2nd are not equal because right padding of the first column takes the space from it.
    This is how I fixed it: I added padding to all the columns at their both sides (10px left and 10px right). This will of course expand .grid by 20px (10px left @ the 1st one and 10px right @ the last one) causing problems. I fixed it with the negative margines on .grid like so:

    
    [class*='col-'] {float:left; padding:0 10px;}
    .grid { margin: 0 -10px;}
    

    Give it a shot. It works for me.

    • You can also do this:

      .grid {
          overflow: hidden;
          margin-left: -20px; /* same as your gutter */
      }
      [class*="col-"] {
           padding-left: 20px;
      }

  49. Permalink to comment#

    I had to create a responsive grid-based site which worked ie7+ and couldn’t find something I like on the internet so I created my own (based on different grid systems around the interwebz). It allows to combine fixed width and fluid width columns on a single row and works ie7+ (through js). I’m not really an experienced front ender so I’d like to have some comments or critiques.
    Thanks in advance :)
    find it at http://www.pataphysicalturkey.ch/less_test/

    Jonas

  50. viktor
    Permalink to comment#

    Great article, I would check more into web mobile and Grid.

  51. kivovo
    Permalink to comment#

    Chris, this is so cool. Has to be one of my best. LOved it.

  52. Great! Many thanks for this useful post.
    I hadn’t realised that rather than making my life simpler by using grid frameworks like 960 grid system, I was actually making my work more complicated…

  53. Thanks chris for this beautiful and knowledgeable post,i am a css beginner, i read it in a go with each and every comments. it was very interesting and helpful
    thanks again

  54. Permalink to comment#

    Great article, but …oh no! I still cant stop over thinking. Actually my one concern would be nested grid components in fluid grids, as on on your sample. I would be curious to know what your best practice for handling those is.

  55. I am so going to have to come back to this – with a grid system I used recently it was *far* too complicated *and* had to keep adjusting the column width because of the padding issue – I didn’t know there was a trick which forces the column to stay that width regardless of padding/margins etc.

    So thanks!

  56. I like the comment, if you want it work on IE 7 – use something else. Setting ‘box-sizing’ to ‘border-box’ is a beautiful solution until exactly then.

  57. If you’re targeting IE10 or Windows 8 you can use -ms-grid and it’s pretty sweet! I know it doesn’t work for targeting the broad web, but when you make Windows 8 apps using HTML/CSS/JS, the grid system is very nice. Check it out at http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_grid.htm. Oh, BTW, there’s a good implementation of flexbox too and a WinJS (that’s the JavaScript library on Windows 8) control called a ViewBox that will scale and translate its contents automatically when the layout changes.

  58. Hello everyone. Just wanna say I’ve been thinking about creating my personal lightweight CSS Framework that would include a grid system and I thought what Chris presented here was so great it became (though modified) a milestone in my project called “Kaleidoscope”. You can find it right here: https://github.com/emilbrann/Kaleidoscope. If anyone would like to give it a go and give me some feedback that would be fantastic! Thanks ;)

  59. Permalink to comment#

    Matt Berridge:
    “If you wanted equal gutters even when nested could use fixed gutters (em) instead of % which would work…”

    I was referring to the compounding of percentages. For example, what if you had a 7/8 col… that needed to contain a 3/7 col and a 4/7 col?

  60. @Matt Berridge:

    Yes, you’re right. I think the point got lost somewhere (as it often does) when people try to do percentages in web design.

  61. Permalink to comment#

    I like the idea of coding my own grid like this, specifically because with a lot of frameworks it’s hard to know what’s going on in the background.

    But I too wonder how you would deal with nested columns using this method? From what I can tell, all nested columns would contain padding on their right sides, including the last one, making them out of alignment with the grid. Is there an easy fix for that?

    • Erik
      Permalink to comment#

      I’d like an answer to this as well. I haven’t been able to figure anything out.

  62. Permalink to comment#

    Chris; This so simple grid has saved my life today!

    I’ve been having issues with using WordPress and using a .last class on a thumbnail gallery. Which is very common of responsive frameworks such as Bootstrap(?) and 1140 etc.

    Thanks again.

  63. Permalink to comment#

    I’m using the Foundation framework which also utilizes box-sizing: border-box; and padding for left and right gutters. Here’s my issue with that:

    If every column has padding (as gutters) that means I can never have a div inside a column with a background or a top/bottom border that bleeds all the way to the left and right edge of that column. This is something I often design for, but now can’t easily implement with this gutter system. There will always be padding which prevents my child div from touching the very edge of the parent div (column).

    Any thoughts, or has anyone else come across the need to visually display something inside to the edge of a column?

  64. sugarfreejones@gmail.com
    Permalink to comment#

    What subtle CSS behavior am I missing that explains why we can’t use $pad all they way around the grid; ie:


    /* Opt-in outside padding */
    .grid-pad {
    padding: $pad
    }

    I see WHAT happens when we do this: We get the correct outside padding on the grid, but the last column expands a bit wider (into it’s gutter padding). I just don’t understand WHY.

  65. williammalo
    Permalink to comment#

    I made a stylus mixin to automate this:

    grid(columns, mod=1, gutter=2%)
        display:inline-block
        vertical-align:top
        margin:gutter 0 0 gutter
        width:(((100%/columns)*mod)-((gutter*(columns+mod))/columns))

    To make a 1-3 box:

    .box{
        grid(3)
    }

    To make a 2-3 box:

    .box{
        grid(3,2)
    }

    It can probably be converted to sass or whatever.

    • Brian Danin wrote in with a Sass port:

      $pad: 2%;
      @mixin autogrid($columns,$mod:1,$gutter:$pad){
         display:inline-block;
         vertical-align:top;
         margin:$gutter 0 0 $gutter;
         width:(((100%/$columns)*$mod)-(($gutter*($columns+$mod))/$columns));
      }
      
  66. Gareth Alexander
    Permalink to comment#

    @jochem I think its to do with the span widths, span4 / span8 etc are all assuming the spans are the same size, where as with div-1-3 / div-2-3 can be used in a system where the “spans” can be variable. div-1-3 means column of span 1 of a total of 3 spans, which when calculated is calculated out to be a third of the screen width with padding, margins etc, you can then also have div-1-4 which is 1 span of 4 which means each of the spans are effectively 25% width.

  67. nena
    Permalink to comment#

    hi! I am trying to use your sass code but I keep on getting this error while comipiling: syntaxerror on line[¨24¨] of C:/path/config.rb:11: sytax error, unexpected tINDENTIFIER, expecting end of input @ mixin box-zinzing $pad

    I seem to get no solution on this.. maybe you can help?

  68. Matt
    Permalink to comment#

    Am I not getting it or am I the only one who cares about the columns not being equally wide!?

    • Trevor
      Permalink to comment#

      Agreed, equal width columns are VERY necessary in many cases in my mind. Thanks for posting such a clear example of how the columns are not equal with this solution. So while this grid option is a great idea, far better than most of the crazy grids out there, I agree the un-even columns this is flaw.

      But I’ve had very good success implementing the negative margin fix posted in this comment above. It probably wouldn’t work in all cases, but if you setup your containing element carefully it does provide a nice solution that enables you to keep using this fantasticly simple grid solution. I for one have had good success with it so far in my website builds.

  69. India
    Permalink to comment#

    Chris, I’m struggling, I’m currently taking your lynda.com course WordPress 3: Creating and Editing Custom Themes and I’m attempting to get my css and html in order so I can get this theme going. I want 2 sidebars (left & right) and a center (for main content)….can you offer some help because it’s not working for me.

  70. Paul
    Permalink to comment#

    By no margin is this simple or easy to read.

    Have you edited grids in a sane framework?

    <Grid>
      <Grid.ColumDefinitions>
        <ColumDefinition Width="0.1*"/>
        <ColumDefinition Width="*"/>
        <ColumDefinition Width="Auto"/>
        <ColumDefinition Width="56"/>
      </Grid.ColumDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Width="0.1*"/>
        <RowDefinition Width="*"/>
      </Grid.RowDefinitions>
    
      <TextBox Grid.Column="0" Grid.Row="1" Text="..."/>
      ..
    </Grid>
    

    WPF, for example, has WrapPanels (similar to HTML), StackPanels (horizontal, vertical), Grids, Canvas, etc. It is as easy to create simple or complex patterns as drinking a glas of milk.

    I don’t know why web developers are so submissive. There is something inherently rotten in the way the W3C has constructed the web and if no one says anything except “oh, we just paste a dirty hack here and then it won’t collapse” then nothing is going to change!

    This:

    .grid {
      background: white;
      margin: 0 0 $pad 0;
    
      &:after {
        /* Or @extend clearfix */
        content: "";
        display: table;
        clear: both;
      }
    }
    
    [class*='col-'] {
      float: left;
      padding-right: $pad;
      .grid &:last-of-type {
        padding-right: 0;
      }
    }
    

    Is not a grid. It is a cryptic, alien mess pile and it is no wonder the web looks as sorry as it does because few designers can put up with that sort of abusive language that HTML/CSS really is and it’s no wonder they grab custom-element libs to get at least readability back.

    At this point i hope Google will replace JS with Dart and HTML with sane custom tags. We could run native like content easily in our browsers if it weren’t for these insane languages.

  71. David Ravine
    Permalink to comment#

    I’ve got a text wrap issue with one of the paragraphs inside the divs (non-modified from the original example).

    Example Pen

    It only happens with some text strings, but they are not especially long or abnormal in any way.

    Can anyone tell me why this happens ? The CSS is pretty simple in itself so it really puzzles me how this paragraph overflow suddenly happens? It’s like it suddenly doesn’t restrict itself to the size of the div.

  72. Chad Lummis
    Permalink to comment#

    Well I recently decided to roll my own grid and simply it as far as I could go. I wanted to think in terms of (MED). What is the minimum effective dose for a fluid grid framework without all the jazz of most frameworks. I was inspired by the “dead simple grid” (http://mourner.github.io/dead-simple-grid/).

    My grid uses no gutters. Rather, I figure out the gutter for the content after I place the content on the page. The process I use is to code everything without any visual styles, that way I work out the visual layout first. I learned the hard way that styling too early makes more work debugging CSS later. Please critique, because I may have over simplified.

    I create columns by combining my .content class with a “size” class (.col-1, .col-2, .col-3., etc). I only go to 10 columns, rather than the typical twelve. This makes it simple percentages and easy to nest (10%, 20%, etc.). Besides, layout is more about combining columns to break the page into layout blocks (sidebar, rightContent, etc.). So I do not see the need to stick to the 12 column that exists in most frameworks.

    I only use this initially when developing the site. I change all my grid CSS from .content .col-3 to more semantic CSS .sidebar once the initial layout of the site is developed.

    I am not going to include my reset and normalize CSS, because that is a given in most frameworks these days.

    My Infant Grid with some class helpers.


    /* Row */
    .wrapper { display: inline-block; width: 100%; }


    /* Content */
    .content { float: left; }


    /* .content media query for mobile */
    .content { float: none; width: 100%; display: inline-block; }


    /* Size class for .content */
    .col-1 { width: 10%; }
    .col-2 { width: 20%; }
    .col-3 { width: 30%; }
    .col-4 { width: 40%; }
    .col-5 { width: 50%; }
    .col-6 { width: 60%; }
    .col-7 { width: 70%; }
    .col-8 { width: 80%; }
    .col-9 { width: 90%; }
    .col-10 { width: 100%; }


    /* Global Layout Helpers */
    .left { float: left; }
    .right { float: right; }
    .clear { clear: both; }

  73. riwakawd
    Permalink to comment#

    I think don’t over think it grids is the best finally understood it. I have done my version of it now.

    http://codepen.io/riwakawebsitedesigns/pen/iCEsu

    http://codepen.io/riwakawebsitedesigns/full/iCEsu

    With content after classes for device testing.

  74. sunyen
    Permalink to comment#

    trying to understand the grid-pad’s right padding in Chris’ code:

    /* Opt-in outside padding /
    .grid-pad {
    padding: 20px 0 20px 20px;
    }
    .grid-pad [class
    ='col-']:last-of-type {
    padding-right: 20px;
    }

    Why not just state it with one line to achieve the same result?

    /* Opt-in outside padding */
    .grid-pad {
    padding: 20px;
    }

    Am I missing anything here? Thanks

  75. Martin Johan Klasson

    Hi Frontend-people, and everyone else ;)

    I went back to this article to solve my own dilemma of using a 3 columns solution for myself using fluid columns.

    My dilemma was that the third column got a little wider.. so I went back here to steal som code. But to no avail.

    In your code, with using 3 columns “col-1-3″ makes the last div to be having more width than the two other thirds.

    You can see a fork of my demo here

    But with all these comments above, I still feel that this should have been resolved?

  76. Marc Smedz

    Ok so I have struggled with this for a while as I can’t get the desired effect. I done a 3 column layout with the same theory here, column sizes at 33.33%, used the clear fix etc etc. I then added a background color to my columns only to find they all run into each other and no white space in between. I tried to achieve this by adding margins to the columns to create this but it then breaks the layout and the last column drops down below the others. How can I achieve this?

    CSS –

    *,
    :after,
    *:before {
    margin: 0;
    padding: 0;
    /
    Removes padding behaviour on widths */
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    }

    .row:after {
    content: “”;
    display: table;
    clear: both;
    }
    .row {
    margin-bottom:10px;
    }

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

    [class='col-'] {
    padding-left: 20px;
    }
    [class
    ='col-']:last-of-type {
    padding-left: 0;
    }

    /* Column widths */

    .col-1 {width:100%}
    .col-2 {width:50%}
    .col-3 {width:33.33%}
    .col-4 {width:25%}
    .col-5 {width:20%}

    /* End column widths */

    .col-1 {background:blue;
    }

    .col-3 {
    background:red;

    }

    .col-1 p {
    text-align:center;
    }

  77. Marc Smedz

    Never mind. I’ve figured it out, all I needed to do was pull my head out of my ass and it worked fine, now with white space as desired

  78. Marc Smedz
    Permalink to comment#

    Just run into another problem in that now I have added the margins in the layout breaks on IE8, works fine in firefox. How do I write a hack for IE to fix this?

    CSS

    *,
    :after,
    *:before {
    margin: 0;
    padding: 0;
    /
    Removes padding behaviour on widths */
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    }

    .row:after {
    content: “”;
    display: table;
    clear: both;
    }
    .row {
    width:98%;
    margin:0 auto;
    padding-bottom:0.8%;

    }

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

    [class='col-'] {
    margin-right: 1.6%;
    padding:10px;
    }
    [class
    ='col-']:last-of-type {
    margin-right: 0;
    }

    /* Column widths */

    .col-1 {width:100%}
    .col-2 {width:49.2%}
    .col-3 {width:32.26%}
    .col-4 {width:23.8%}
    .col-5 {width:20%}

    /* End column widths */

    .col-1 {background:blue;
    }
    .col-1 p {
    text-align:center;
    }

    .col-2 {background:green;
    }

    .col-3 {
    background:red;

    }

    .col-4 {
    background:yellow;

    }

  79. Alex
    Permalink to comment#

    What is the cleanest way to add a background colour to the grid – is it considered clean practise to add a second class to the grid div or should it go on another element?

    The reason I ask is I feel it’d be cleaner house keeping to keep all these types of styles within the modules but I’m then not sure how to apply a background colour on what Ideally would be placed on the grid’s div.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".