---
title: Neat 2.0 Building the future of floated Sass grids
teaser: 'Understanding different types of existing float grid systems, finding their
  strengths/weaknesses, and discovering something better.

  '
tags: neat,bourbon,design,sass,open source,web
author: Will H McMahan
published_on: 2017-02-22
---

<style type="text/css">
svg {
  color: inherit;
}

@media (min-width: 700px) {
  .full-width-image {
    margin-left: calc(350px - 50vw) !important;
    min-width: calc(100vw - 3rem) !important;
  }
}
@media (min-width: 1366px) {
  .full-width-image {
    margin-left: calc(365px - 50vw) !important;
    min-width: calc(100vw - 3.25rem) !important;
  }
}

.small-image {
  max-width: 400px !important;
  margin: 4rem auto !important;
}

.super-small-image {
  max-width: 150px !important;
  margin: 4rem auto !important;
}
</style>

<img src="https://images.thoughtbot.com/blog-vellum-image-uploads/Mb3tc3hLSnyuvCKJBOsF_Illustrations-v2-no-gradient.svg"
  class="full-width-image"
  alt="An illustration of the game snakes and ladders made to look like a grid"
/>

Version 2.0 of Neat has been released.

New and improved, this change is a substantial departure from its original
attributes and behavior. The result is a simpler, more flexible system that
allows you to more rapidly create sites and apps. These changes represent over a
year's worth of work and iteration. We have also updated [Neat's
website](http://neat.bourbon.io), and
[documentation](http://neat.bourbon.io/docs). The following is a breakdown of
how grids function across the web and just what makes Neat 2.0 different.

→ [tl;dr](#the-push-left-grid)

As I have worked on the web, I have always been fascinated with grid systems.
While I have used and contributed to quite a few libraries, they have never
quite met my needs. More often than not, these libraries behave unpredictably,
use things like nth-child selectors, and dump huge amounts of unnecessary code
to your project. There are a couple of things at play here however. Mostly when
people say “grid system” their actual expectations of what a grid system should
handle can vary wildly. On top of this, it’s also important that concept and the
execution are two separate things. Some libraries will have a great code quality
and technical implementation of a mediocre initial idea while others take good
concepts but execute them poorly.

I tend to focus on the idea itself: what makes a grid, what problems is it
trying to solve, is it flexible, is it simple, does it help me when I need it
and stay out of my way when I don't.

While I use flexbox to some extent on most of my projects, and I look forward to
the implementation of the CSS Grid Layout spec, the fact is that most people
still use floats to build the page and create layouts. Also, even as new
features are added to CSS, it does not mean that features like float go away,
and will likely continue to be valid solutions for particular issues.

That said, most float based grid systems fall in to three main categories:

- [Half-gutter grids](#the-half-gutter-grid)
- [Simple-gutter grids](#the-simple-gutter-grid)
- [Percentage grids](#the-percentage-grid)

<img
  src="https://images.thoughtbot.com/blog-vellum-image-uploads/pU40HseMTP2ifKh8xfLm_spot-1.svg"
  class="small-image"
/>

In thinking about this further, I went down quite the “there has to be a better
way” rabbit hole, and in doing so created a new paradigm I think is superior to
its predecessors, a `calc` based **[Push-left grid](#the-push-left-grid)**. Neat
2.0 uses this new system to achieve dynamic responsive layouts that were not
possible with the other three.

It is worth mentioning that liking/disliking a particular grid will always come
down to a bit of personal flavor and what your expectations of a grid framework
are. That said, there are few things any grid framework should shoot for:

- Low selector specificity and no nth-child selectors
- Gutters that can be defined in relative values like `2%` as well as fixed
  values like `2rem` or `16px`
- A simple and understandable codebase with a limited set of well focused features
- Generate as little code as possible, maintaining flexibility, while not over
  restricting objects
- Coexist seamlessly with flexbox objects and containers
- Be compatible with both Lib Sass and Ruby Sass

<img
  src="https://images.thoughtbot.com/blog-vellum-image-uploads/abShNjB3Q924YeQI3J0n_spot-2.svg"
  class="super-small-image"
/>

## The Half-gutter grid

The earliest CSS grid systems were Percentage-grids and Half-gutter grids.
Despite the weird name that I've given them, Half-gutter grids are probably the
most simple. Like all grids, they start with the number of core variables:
gutter width, number of columns.

Half-gutter grids work on the basic principle of gutters being shared between
all of the objects in the layout. The parent container or `row` has an internal
horizontal padding. The padding on each side is equal to one half of the gutter
width. The system then relies on each `column` also having horizontal padding
equal half of the gutter width, which provides the other half of the full
gutter. When two columns come together, each of them provides half of the
gutter, to make a whole. Similarly, when one side of the interior `column` comes
in contact with the `row`, each of them has a half a gutter of padding. This
means that you end up with a series of columns and a consistent gutter width
between them, including a full gutter on each end.

This system has a lot of benefits. One of the biggest is that it allows you to
have a fixed value as a gutter width (`1rem`) and a relative value for your
column width (`25%`). Due to the way widths are calculated, half-gutter grids
end up with nice sensible percentages for their width values, like `25%`,
`33.333%`, etc. This feature makes them a little easier to debug when things go
awry. It also allows for complex layouts with multiple columns that can also
reflow as needed. Examples of this style of grid can be found in Zurb's older
versions of Foundation as well as early versions of Bootstrap. Although it is a
more intricate variant, Susy by Oddbird uses half-gutter grids to handle
spacing.

<svg
  width="100%"
  height="100%"
  viewBox="0 0 1024 500"
  version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  class="full-width-image"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  xml:space="preserve"
  style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.41421;"
  aria-labelledby="title"
  aria-describedby="desc"
  role="img">
  <title id="title">Half gutter Grid</title>
  <desc id="desc">An illustration of how half-gutter grid objects interact with
    their surroundings</desc>
  <rect id="Artboard2" x="0" y="0" width="1024" height="500"
    style="fill:none;"
  />
  <use xlink:href="#svg-image-1" x="97" y="130" width="830px" height="240px"/>
  <rect x="227" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="367" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="508" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="647" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="788" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="927" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="157" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="297" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="438" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="577" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="718" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="857" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="232" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="372" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="513" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="652" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="793" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="932" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="162" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="87" y="376" width="5" height="19" style="fill:#737373;"/>
  <rect x="92" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="302" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="443" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="582" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="723" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <rect x="862" y="376" width="5" height="19" style="fill:#8c8c8c;"/>
  <path d="M865,449.7l71,0"
  style="fill:none;stroke:currentColor;stroke-width:1px;"/><g
  transform="matrix(1,0,0,1,21,-4037.04)"><text x="684.638px" y="4485px"
  style="font-family:inherit;fill:currentColor;font-weight:400;font-size:1em;">container</text><text
  x="773.427px" y="4485px"
  style="font-family:inherit;fill:currentColor;font-weight:400;font-size:1em;">padding</text></g><path
  d="M232,404.919l0,44.781l5,0l0,-45"
  style="fill:none;stroke:currentColor;stroke-width:1px;"/><path
  d="M296.494,404.919l0,44.781l5,0l0,-45"
  style="fill:none;stroke:currentColor;stroke-width:1px;"/><path
  d="M932,404.919l0,44.781l4.287,0l0,-45"
  style="fill:none;stroke:currentColor;stroke-width:1px;"/><path
  d="M354,449.7l-122,0"
  style="fill:none;stroke:currentColor;stroke-width:1px;"/><text x="360.9px"
  y="447.964px"
  style="font-family:inherit;fill:currentColor;font-weight:400;font-size:1em;">padding</text><text
  x="96.543px" y="42.136px"
  style="font-family:inherit;fill:currentColor;font-weight:400;font-size:1em;">container</text><path
  d="M98.008,119.478l0,-56.781l829.992,0l0,57"
  style="fill:none;stroke:currentColor;stroke-width:1px;"/>
  <defs><image id="svg-image-1" width="830px" height="240px"
  xlink:href="data:image/png;base64,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"/></defs>
</svg>

Half-gutter grids do however have one significant limitation. Since they rely on
multiple objects interacting with each other to create a single gutter, all the
objects in layout have to use the grid system. This means that once a `row`
defined, all it's direct children need to be columns and that custom layouts and
modifications to the standard grid become more and more difficult as the project
grows. While this is a bit of a philosophical difference, the end result is that
the designer is the one who has to serve the needs of the grid instead of the
grid serving and empowering the designer.

### The Simple-gutter grid

The Simple-gutter grid is a more simplified variant of a half gutter grid which
more closely resembles something that you might create manually. These
Simple-gutter grids follow the same tools as above, but don't bother giving
their `row` objects any padding. That means that the spacing between the first
`column`'s content and the edge of the row is the width of 1 gutter value but
the spacing between 1 `column`'s content and another `column`'s is 2 gutters.

At the end of the day, hand writing a system like this might look something as
simple as:

```scss
$gutter: 1rem;

.col-1 {
  float: left;
  padding: 0 $gutter;
  width: percentage(1/3);
}

.col-2 {
  float: left;
  padding: 0 $gutter;
  width: percentage(2/3);
}

// 🎉 You made a grid!
```

## The Percentage grid

I remember the first Percentage grid I saw. It was on the site for [Responsive
Grid System](http://www.responsivegridsystem.com/) and was the coolest thing I'd
seen. During the rise of responsive design, percentage grids grew in popularity
since they matched the growing future of the fluid multi-device world so well.

Percentage grids are really based around a single idea. All values are
percentages, and unlike half-gutter grids, this includes the gutters. There are
actually quite a few examples of this out in the wild, including Neat `~1.0` and
many others.

Since the gutters are defined as percentages, `row` objects are often defined
with a percentage value of padding on either side, each equal to one gutter
(sometimes this is defined as a margin on either side instead).

`column` widths are then defined with a calculation that resembles the
following:

    column number / total columns * 100% - (column number / total columns * gutter)

This means that columns are calculated by determining the number of grid columns
that a `column` object should span, excluding the object's gutters.

<svg width="100%" height="100%" viewBox="0 0 1024 500" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve" class="full-width-image"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.41421;"
aria-labelledby="title" aria-describedby="desc" role="img"> <title
id="title">Percentage Grid</title><desc id="desc">An illustration of how
Percentage grid objects interact with their surroundings</desc><rect
id="Artboard2" x="0" y="0" width="1024" height="500" style="fill:none;"/><use
xlink:href="#svg-image-2" x="97" y="130" width="830px" height="240px"/><path
d="M227,393.956l0,55.781l10,0l0,-70"
style="fill:none;stroke:currentColor;stroke-width:1px;"/><path
d="M865,449.737l60,0l0,-70"
style="fill:none;stroke:currentColor;stroke-width:1px;"/><path
d="M279,449.737l-52,0"
style="fill:none;stroke:currentColor;stroke-width:1px;"/><g
transform="matrix(1,0,0,1,21,-4037)"><text x="575.757px" y="4485px"
style="font-family:inherit;font-weight:400;font-size:1em;fill:currentColor;">:<tspan
x="581.14px 591.389px 597.694px 607.943px 617.521px 626.036px 636.286px
641.231px 646.176px 656.566px 662.09px 672.339px " y="4485px 4485px 4485px
4485px 4485px 4485px 4485px 4485px 4485px 4485px 4485px 4485px
">nth-child(n)</tspan></text><text x="694.182px" y="4485px"
style="font-family:inherit;font-weight:400;font-size:1em;fill:currentColor;">{<tspan
x="699.705px 714.963px 724.119px 730.986px 741.282px 746.227px 756.477px
766.055px 772.922px 777.867px 788.163px 798.413px 804.717px " y="4485px 4485px
4485px 4485px 4485px 4485px 4485px 4485px 4485px 4485px 4485px 4485px 4485px
">margin-right:</tspan></text><text x="810.1px" y="4485px"
style="font-size:1em;fill:currentColor;">0</text><text x="826.42px" y="4485px"
style="font-family:inherit;font-weight:400;font-size:1em;fill:currentColor;">;<tspan
x="831.802px " y="4485px ">}</tspan></text></g><text x="285.9px" y="448.001px"
style="font-family:inherit;font-weight:400;font-size:1em;fill:currentColor;">m<tspan
x="301.158px 310.314px 317.18px 327.477px 332.422px 342.672px 352.25px 359.116px
364.061px 374.358px 384.608px " y="448.001px 448.001px 448.001px 448.001px
448.001px 448.001px 448.001px 448.001px 448.001px 448.001px 448.001px
">argin-right</tspan></text><text x="96.543px" y="42.137px"
style="font-family:inherit;font-weight:400;font-size:1em;fill:currentColor;">c<tspan
x="105.059px 115.207px 125.457px 131.761px 140.917px 145.862px 156.112px
165.346px " y="42.137px 42.137px 42.137px 42.137px 42.137px 42.137px 42.137px
42.137px ">ontainer</tspan></text><path
d="M98.008,119.48l0,-56.782l829.992,0l0,57"
style="fill:none;stroke:currentColor;stroke-width:1px;"/><defs><image
id="svg-image-2" width="830px" height="240px"
xlink:href="data:image/png;base64,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"/></defs></svg>

Percentage grids also tend to have another characteristic. Unlike half-gutter
grids, Percentage grids tend to only have gutters between columns and not on
either end of the row. While there is no technical necessity for this, it can be
seen in Responsive Grid System, Neat, and Profound Grid. This attribute has the
side effect of often relying on `nth()` selectors to make sure that the last
column in any row does not have any margin. An example of this is Neat’s `omega`
mixin that removes the right margin.

## The Push-left grid

I have consistently struggled with grids never quite fitting my needs. In almost
any project, I end up hand writing grid styles for each module. As long as you
keep things simple this is rarely an issue. However, it can make a code base
more prone to fragmentation as well as making it more difficult to onboard new
people to work on the project. Often times a system doesn't need to solve every
problem, but instead present a set of simple and unobtrusive defaults that a
developer/designer can choose to use or not depending on they needs.

With that, I worked on developing a system I would be comfortable using on
production code, that had a few core values:

1. Simple to use
2. As few attributes defined on a single element as possible
3. No `:nth-child()` child selectors
4. Plays nicely with flexbox
5. The ability to *push/pull* columns and to reorder them (as best as floats can
   handle)
6. Seriously… it need to be like stupid simple to use

This lead me to Push-left grids. The basic principle is that you use `calc()` to
determine exactly how wide a grid object should be, and then use this
calculation to predict and accommodate for the object’s gutter and the gutter of
its siblings. The “push left” comes from the idea that instead of a `column`
using its `margin-right` to push the following `column` away, these columns use
`margin-left` to push themselves away from the row or their preceding siblings.
This all works thanks to this rather complicated equation.

```css
width: calc(percentage($columns / $grid-columns) - $grid-gutter + ($grid-gutter * percentage($columns / $grid-columns)));
```

Basically what is happening is that each column is responsible for handling a
few items:

1. Its base width in percentage, for example a column that is `3` out of a total
   columns of `12` would be `25%`
2. Its own `margin-left`, aka 1 `$grid-gutter`
3. Its share of the *extra gutter*.

A basic grid will always have 1 extra gutter as compared to the total number of
columns: A 4 column grid will have 5 gutters, a 6 column grid will have 7
gutters, a classic 12 column grid will have 13 gutters, and so on. This means
that each column has to accommodate space for its own gutter as well as its
share of the extra gutter, which is directly relational to its base
width percentage. This means that a 6/12 column will have to accommodate for 1
and a half gutters, the 1 being its gutter and the half being it’s share of the
extra gutter.

<svg width="100%" height="100%" viewBox="0 0 1024 500" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve" class="full-width-image"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.41421;"
aria-labelledby="title" aria-describedby="desc" role="img"> <title
id="title">Push-left Grid</title><desc id="desc">An illustration of how
Push-left grid objects interact with their surroundings</desc><rect
id="Artboard2--Artboard-" x="0" y="0" width="1024" height="500"
style="fill:none;"></rect><use xlink:href="#svg-image-3" x="97" y="130"
width="830px" height="240px"/><path d="M871,449.7l65,0"
style="fill:none;stroke:currentColor;stroke-width:1px;"/><g
transform="matrix(1,0,0,1,27,-4037.04)"><text x="725.368px" y="4485px"
style="font-family:inherit;fill:currentColor;font-weight:400;font-size:1em;">e<tspan
x="734.602px 749.86px 760.25px 766.554px " y="4485px 4485px 4485px 4485px
">mpty</tspan></text><text x="791.554px" y="4485px"
style="font-family:inherit;fill:currentColor;font-weight:400;font-size:1em;">s<tspan
x="800.03px 810.42px 819.576px 828.091px " y="4485px 4485px 4485px 4485px
">pace</tspan></text></g><text x="86.543px" y="42.439px"
style="font-family:inherit;fill:currentColor;font-weight:400;font-size:1em;">c<tspan
x="95.059px 105.207px 115.457px 121.761px 130.917px 135.862px 146.112px
155.346px " y="42.439px 42.439px 42.439px 42.439px 42.439px 42.439px 42.439px
42.439px ">ontainer</tspan></text><path d="M87,119.781l0,-56.781l850,0l0,57"
style="fill:none;stroke:currentColor;stroke-width:1px;"/><path
d="M87,393.919l0,55.781l10,0l0,-70"
style="fill:none;stroke:currentColor;stroke-width:1px;"/><path
d="M928,393.919l0,55.781l10,0l0,-70"
style="fill:none;stroke:currentColor;stroke-width:1px;"/><path
d="M139,449.7l-52,0"
style="fill:none;stroke:currentColor;stroke-width:1px;"/><text x="145.9px"
y="447.964px"
style="font-family:inherit;fill:currentColor;font-weight:400;font-size:1em;">m<tspan
x="161.158px 170.314px 177.18px 187.477px 192.422px 202.672px 212.25px 217.195px
226.429px 232.631px " y="447.964px 447.964px 447.964px 447.964px 447.964px
447.964px 447.964px 447.964px 447.964px 447.964px
">argin-left</tspan></text><defs><image id="svg-image-3" width="830px"
height="240px"
xlink:href="data:image/png;base64,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"/></defs></svg>

This means that the space left over after all the columns in a row have been
filled is exactly 1 gutter. The extra nice thing about this is that if one
browser choses to round differently, it wont break the layout because the final
column is empty space. It is nearly impossible to break layout and have a column
pop down to the next row when it wasn’t supposed to (I’m sure this has happened
to everyone, haha).

### Simplicity

A tool like this has some complicated math. Using `calc()` in Sass is not the
easiest thing in the world. However, this is what makes it great territory for
a framework. The complexities of a particular calculation can be abstracted away
from the user, allowing them to focus on taking their vision to the digital
page. Ultimately there are only a few limited features that should be in a grid
framework: push/pull items away or toward each other, relative position
reordering or “shifting” for use on responsive layouts, integration with media
queries for dynamic responsive grids, and an api that is flexible and easy to use.

### As few attributes defined and lowest specificity as possible

This may be the single best feature of a Push-left grid. Grids will always have
a bit of complexity. Fortunately for a system like this, all the complexity is
hidden within a single easily overridden attribute, `width`. Other than the
width definition, the only required attributes are `float: left` and
`margin-left: $grid-gutter` which are the same for every element within the
system.

Since their is no “you are the last column, make sure you don't have a
margin” issue there is also no need for `:nth()` selectors at all. This
also means that when you change column counts based on screen size, their is
nothing to reset via overrides.

### Play nicely with Flexbox

There are so few definitions within a push-left system, its easy for a `column`
in a system like this to have flexbox siblings, parents, children, and to even
become a flexbox object itself! If you were to have two columns
that were predefined with a 4 of 12 column width, and flex was applied to the
parent, the object's behavior would not even change, but would then allow you to
use flex attributes to further manipulate the objects within.

## Neat v2.0.0

Neat `v2.0.0` is an Sass based Push-left grid system that uses these concepts
and builds upon them to create a solid scalable grid framework. It is built on
clever tactics and the learnings of its predecessors to create simple
grids that are flexible enough for any project.

[![Logos for Rubygems, NPM, and Bower](https://images.thoughtbot.com/blog-vellum-image-uploads/iti2oFKoRd2ZAgmhEiOn_grid-illus.jpg)](http://neat.bourbon.io)

A grid will never solve every use case and probably shouldn’t, but the most
important thing is to create a concise and understandable system that
empowers the user to write awesome code and create amazing designs without
getting in the way. Ultimately, it is the job of the grid to serve the
designer/developer and not the other way around. If you have sat looking at the
css that some grid system spit out and thought “What the hell is going on here”,
you should probably try the new [Neat 2.0](http://neat.bourbon.io/). 😘

Thank you to [everyone who has contributed to
Neat](https://github.com/thoughtbot/neat/graphs/contributors), as it continues
to evolve, grow, and thrive in a vibrant community of designers and developers.

Sincerely yours,<br/>
[Will H McMahan](https://twitter.com/WHMII)
