#132: A Quick Useful Case for Sass Math and Mixins

I had a little design situation come up where I was making a fluid grid of boxes with floats. I wanted to specify how many boxes across a row was very easily, and have them flush against both edges of the container. Not too difficult, as we know from not overthinking grids and using the right box-sizing, you can get four floated boxes in a row width 25% width - easy.

But what if you want to use margin between the boxes? Still totally possible, just requires some thinking. Say you want four in a row, you'll need to figure out how much space you have left after all the margin is used. Because you don't want margin on the last one in the row, that's 3 margins:

100% - (3 * MARGIN)

3 is really "rows you want minus one", so:

100% - ((ROWS - 1) * MARGIN)

Then you divide the space you have left by how many boxes you want on that like, so:

(100% - ((ROWS - 1) * MARGIN)) / ROWS

You could use Sass for that:

$numPerRow: 4;
$margin: 2%;

width: ((100% - (($numPerRow - 1) * $margin)) / $numPerRow);

Even better, we make that into a @mixin, so we can just call it whenever we need it:

@mixin rowMachine($numPerRow, $margin) {
  width: ((100% - (($numPerRow - 1) * $margin)) / $numPerRow);
  &:nth-child(n) {
    margin-bottom: $margin;
    margin-right: $margin;
  &:nth-child(#{$numPerRow}n) {
    margin-right: 0;
    margin-bottom: 0;

Watch the video to learn about that tricky bit with :nth-child

In the video, the bit in the beginning with the Jade loop you can learn more about here.

And here's the Pen:

See the Pen Simple Technique for using Sass for Rows by Chris Coyier (@chriscoyier) on CodePen.


  1. User Avatar
    Marco Biedermann
    Permalink to comment#

    I used something similar with a image gallery but without some comlpicated math. Works pretty well!
    Use negative margins to fix the padding of the elements.

    img {
      display: block;
      max-width: 100%;
    .gallery {
      ul {
        @extend .cfx;
        list-style: none;
        margin: -.25em;
        padding: 0;
    li {
        @include box-sizing(border-box);
        float: left;
        padding: .25em;
        width: 25%;
        @media (min-width: $media-tablet + 1) and (max-width: $media-desktop) {
            width: 33.33%;
        @media (max-width: $media-tablet) {
            width: 50%;
  2. User Avatar
    Bruno Almeida
    Permalink to comment#

    Amazing that.

    I was just making a rule that lists items and stopped to see the twitter when I came across this.


  3. User Avatar
    Permalink to comment#

    Nice screen-cast :)

    I used something similar for a grid system http://www.get-maze.co.uk/

    /* Variables */ 
    $grid-columns: 12;
    $unit: (100%  / $grid-columns) ;
    $gutter: 2%;
    $push: 0 !default;
    /* Mixin */ 
    @mixin grid($col, $push) {
    @include box-size;
    @include transition;
    width: (($unit * $col) - $gutter ) + ( $gutter / ( $grid-columns / $col) );
    float: left;
    margin-right: $gutter;
      @if $push > 1 {
      margin-left:(($unit * $push) ) + ( $gutter / ( $grid-columns / $push) );
        &:last-child {
  4. User Avatar
    Permalink to comment#

    Sometimes it’s more appropriate to use Susy. Version 2.0 was released earlier this month and it is indeed simple meta-framework with Sass 3.3 dependency. The point is, it’s really simple, but you can make it really complicated with all powerful features and nerd the heck out of it! =)

    Definitely check it out: Susy 2.0

  5. User Avatar
    Permalink to comment#

    Sometimes it’s more appropriate to use Susy. Version 2.0 was released earlier this month and it is indeed simple meta-framework with Sass 3.3 dependency. The point is, it’s really simple, but you can make it really complicated with all powerful features and nerd the heck out of it! =)

    Definitely check it out: Susy 2.0

    update: wrong e-mail address on previous comment

  6. User Avatar
    Permalink to comment#

    Hey Chris,

    Thanks for the video, quick and relatively simple to implement.. but I got a bit lost with the :nth-child(n) bit. Can you explain a bit about how you can use :nth-child on ‘n’ instead of literally specifying something, e.g 4 or 5. Your link to your other article on nth-child didn’t really help me.

    • User Avatar
      Permalink to comment#

      oh wait. I think I get it now!

      with nth-child(n) you give the margin-right to each ‘card’ to ensure it’s got some margin-right in case it moves around and then take it away on the last one with the other use nth-child


  7. User Avatar
    Permalink to comment#

    Ya Chris, and you were thinkin’ out loud on this, it seems we don’t have to specify margin-bottom: 0; on the last in the row, although it doesn’t break anything since the bottom margin is held open by the others in the row.

    Thanks a lot for this video, I love watching and learning from them!

  8. User Avatar
    Richard Dale
    Permalink to comment#

    No support in ie for nth child though so using this you’d need ie9, not much of an issue these days but worth considering.

  9. User Avatar
    Mark Spain
    Permalink to comment#

    Hey Chris, great example! I will definitely be incorporating this into my future projects. I think I may have spotted a problem though… you probably shouldn’t be setting margin-bottom: 0; on nth-child(#{numPerRow}n) because it can cause problems when you set display: block; on an <img />. I made a pen to play around with animating border-width on a grid of image links that illustrates the issue: pen

    Check out what happens when you comment/un-comment the margin-bottom: 0; in the rowMachine mixin.

  10. User Avatar
    Daniel Dogeanu
    Permalink to comment#

    Woah! Awesome! I needed this a looong, long time ago, to display a grid of logos to a client’s site and failed. Now this is how you do it properly! Thanks!

  11. User Avatar
    Guilherme Harrison
    Permalink to comment#

    I believe (from the tests I made on codepen) there is no need for including the margin-bottom: $margin; margin-right: $margin; inside the nth-child(n). You also don’t need to reset the margin-bottom to 0px on the last element of the row.

    Please tell me if I’m wrong.

  12. User Avatar
    Permalink to comment#

    Hmmm, this will be handy, I have a client that requires the homepage to be a metro style, was using flex-box. although wasn’t what I was looking for. Will definitely give this a shot

  13. User Avatar
    Gustavo Caso
    Permalink to comment#

    Thanks Chris.
    Really useful mixins and simple way of handling grid layout.

  14. User Avatar
    Marko B.
    Permalink to comment#

    There is no point in setting margin-bottom: 0; at the last element in a row, it is just obsolete.

  15. User Avatar
    Permalink to comment#

    There is a mixun called omega in neat which does that.

  16. User Avatar

    Great video! It’s now included in my collection of helpfull mixins. I added an extra feature to the mixin, that clears the “row” . Just in case there is an item that has an extra long title. And I also removed the margin-bottom.

    To make it work, I also changed the mediaqueries that called the mixin. Check my codepen and edit one of the titles from “Darth” to ie. “Darth Vader is the fictional character in the Star Wars”.

  17. User Avatar


    I need your help for writing below syntax in Less.

    how could I do it?


  18. User Avatar
    Mikel J McCormick

    Here’s something similar I’ve done to achieve a similar responsive layout:

    // Generate responsive rules
    $max-resolution: 1920px;
    $cell-width: 250px; 
    // actual cell width should = $cell-width ( 1 - ( 1 / ceil( [the-browser-resolution] / $cell-width ) )
    @for $i from 0 to ceil($max-resolution/$cell-width) {
        $min: $i * $cell-width;
        $max: ($i + 1) * $cell-width;
        @include respond-between($min,$max) {
            $width: 100% / ($i + 1);
            .container .cell {
                width: $width;
                &amp;:nth-child(#{$i + 1}n + 1){
                    clear: both; 

    Simple responsive mixin:

    @mixin respond-between($min: 0px, $max: 1920px) {   
        @media only screen and (min-width: $min) and (max-width: $max) { @content; } 

    -Mike McCormick

  19. User Avatar

    You don’t need flexbox… if you use equal height pictures ;-)

  20. User Avatar

    That’s very very cool -thanks

  21. User Avatar
    Robert Brodziak

    Mr. Coyier, you’re the best!

  22. User Avatar
    Permalink to comment#

    SUPER AWESOME! Where were you like 3 weeks ago when I was pulling my hair out trying to make this work!? Thanks for a great screencast!

  23. User Avatar
    Permalink to comment#

    Wow, this is amazing!

  24. User Avatar
    Permalink to comment#

    Tweaked this to also cater for uneven columns and added a breakpoint for responsive column collapse. We’ve named it colMachine in honour of rowMachine.

    @mixin colMachine($width1, $width2, $margin, $breakpoint) {
      width: (0% + ($width1 - ($margin/2)));
      float: left;
      &:nth-child(n) {
        margin-bottom: $margin;
        margin-right: $margin;
      &:nth-child(2) {
        width: (0% + ($width2 - ($margin/2)));
        margin-right: 0;
        margin-bottom: 0;
      &:nth-child(2n + 1) {
        clear: left;
        @media (max-width:$breakpoint) {
        width: 100%;
        padding: 1%;
        &:nth-child(n) {
        margin: 0;
          &:nth-child(2) {
           width: 100%;;
        img {
  25. User Avatar
    Abbas Arezoo
    Permalink to comment#

    I use this all of the time, with a few tweaks thrown in.

    There is a bug in Safari, which also shows on mobile Safari. If you’re creating a grid of block links with display: table applied to the link, any margin you apply displays incorrectly until you hover on the link.

    The simple solution is to wrap your block link in a containing div. Hardly a major issue, but if it’s broken in Safari any iPad/iPhone users get the bug too.

    Here’s a pen showing the issue: http://codepen.io/abbasinho/pen/wmble

    Here’s a pen showing the fix: http://codepen.io/abbasinho/pen/zgmnJ

    • User Avatar
      Abbas Arezoo
      Permalink to comment#

      Please note: you will only see the bug in Safari.

    • User Avatar
      Permalink to comment#

      I tried checking , but i don’t see any bug.
      safari v 5.1.17.

  26. User Avatar
    Permalink to comment#

    I’ve added this, probably already in the comments to ensure the next row is cleared incase you have different height list items :)

    &:nth-child(#{$numPerRow}n+1) {
  27. User Avatar
    Permalink to comment#

    How would this code look like, if the gutter might be 1px?

  28. User Avatar
    Permalink to comment#

    Hi, I’ve just found this and it’ll save me load of time on my next project :-)

    Just wongering is there a way to span rows e.g a grid of 5 but span across 3 so the dispaly would be “col col col(spanned across 3)”

    Hope this makes sense



Leave a Comment

Posting Code!

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.