Using the Bourbon Family Part 2 - Neat

In Part 1 of our series, we looked at how to use Bourbon to simplify web development. Now we will turn our attention to Neat, the most useful member of the Bourbon Family.

What it is

Neat is a “semantic grid framework”. It provides the same kind of responsive grid layout provided by Bootstrap, Foundation, and others, but allows you to generate it using semantic markup.

How To Use It

The best way to describe Neat is through an example. I whipped this one up by combining a similar guide from Minimul and the official Neat example page.

For this example we can reuse the demo project from Part 1. We just need to perform an extra configuration step. Open up the file source/stylesheets/all.css.scss, and uncomment the line that says @import “neat”. Now Neat is available for use.

Next, open up source/index.html.erb. Delete whatever markup you might already have in there, and replace it with the following:

<section class="main">
 <code>outer container</code>
 <div id="content">
   <code>content</code>
 </div>
 <div id="sidebar">
   <code>sidebar</code>
 </div>
</section>

We haven’t yet written any CSS, but take a look at our class names. If we were using Bootstrap, we would have to use class names such as “col-lg-8” and “col-lg-4”. Such names aren’t exactly descriptive, and their sole purpose is to define the section’s position in the grid. This is what Neat aims to eliminate by focusing on semantic markup. With Neat, we can use descriptive class names such as “sidebar”, and still get a nice grid.

Now we will write our CSS. Open source/stylesheets/demo.css.scss, remove whatever’s in there, and replace it with the following:

.main {

  /* boilerplate styling ... */
  background: tint(gray, 30%);
  text-align: center;
  > code {
    display: block;
    padding: em(12);
  }

  /* More boilerplate ... */
  #content, #sidebar {
    text-align: left;
    background: tint(red, 70%);
    padding: 1em;
    > code {
      display: block;
      height: 100px;
    }
  }

  /* This is added to the outermost tag that you want the
     grid layout to apply to. */
  @include outer-container;

  /* This content will span 8 of 12 columns. */
  #content {
    @include span-columns(8);
  }

  /* This content will span 4 of 12 columns. */
  #sidebar {
    @include span-columns(4);
  }
}

As the CSS comments explain, there’s a bunch of boilerplate we can safely ignore. Our first bit of Neat specific code is on line 24. In order to enable Neat, we have to define the outermost tag of the grid using the outer-container mixin. In our case, we applied it to the “main” class, which was then added to our <section> tag.

While the grid is defined, we still need to define measurements for all the elements inside of it. Like Bootstrap, Neat uses a 12 column grid by default. We use the span-columns mixin to define how many of those columns a given element will make up. As you can see, we gave the content section eight columns, and the sidebar four.

Fire up Middleman, and the rendered page should look something like this:

Neat 1

Clearly, the content section is larger than the sidebar, as we desired. We now have a working grid layout and clean, easy to read HTML. Not too bad, eh?

What we don’t have, however, is responsive design. If we change the size of the page, the columns will remain side by side. On a mobile device, where space is limited, it would be better for them to stack on top of each other. Thankfully, Neat allows us to do this, but unlike with Bootstrap, it isn’t enabled automatically. Rather, we will have to activate it manually.

Replace the contents of source/stylesheets/demo.css.scss with this new, updated version:

.main {

  /* boilerplate styling ... */
  background: tint(gray, 30%);
  text-align: center;
  > code {
    display: block;
    padding: em(12);
  }

  /* This is added to the outermost tag that you want the
     grid layout to apply to. */
  @include outer-container;

  /* Neat requires us to manually define "breakpoints" for
     different screen sizes. On screens smaller than 500px,
     the size of the grid will shrink from 12 to 4. */
  $mobile: new-breakpoint(max-width 500px 4);

  /* More boilerplate ... */
  #content, #sidebar {
    text-align: left;
    background: tint(red, 70%);
    padding: 1em;
    > code {
      display: block;
      height: 100px;
    }
  }

  /* This content will span 8 of 12 columns. */
  #content {
    @include span-columns(8);

    /* On mobile screens, this will change the size
       of this element from 8 to 4. */ 
    @include media($mobile) {
      @include span-columns(4);
    }
  }

  /* This content will span 4 of 12 columns. */
  #sidebar {
    @include span-columns(4);

    /* On mobile screens, this will change the size 
       of this element from 4 to 4. We also change the
       color of the element for clarity's sake. */ 
    @include media($mobile) {
      @include span-columns(4);
      background: tint(green, 70%);
    }
  }
}

Neat allows us to define breakpoints for different screen sizes. In this case, on line 18, we are saying that when the screen is smaller than 500px, the size of the grid drops from twelve columns to four. On lines 37 and 49, we use Neat’s media mixin to define what happens to our content and sidebar elements when the breakpoint is reached. In the case of the content, its size is shrunk down to four columns. The sidebar remains the same size, but we’ll change its color (you’ll see why in a bit).

If you reload the page, you will find that the content looks the same as before. However, if you narrow the width of the browser window, the page should change to look like this:

Neat 2

Let’s make sure we understand what’s going on here. When the browser width dipped below 500 pixels, the breakpoint activated, and the grid shrunk from twelve to four columns. The content element also shrunk to four columns, making it span the entire width of the grid. As for the sidebar, there isn’t enough room in the grid to place it next to the content (4 column grid - 4 columns for the content = 0 columns for the sidebar). Neat will instead move it into a new row underneath.

Additional Features

Neat has a nice debugging feature that renders a visual overlay of the grid on your site. You can enable it by adding the line $visual-grid: true; in source/stylesheets/all.css.scss (Just place it before you import Neat itself).

Secondly, while our example went over the basics of Neat, there are a few advanced features for you to explore. You can nest columns within columns, shift the position of columns, and automatically generate table structures. Now that you have a grasp of the basics, I’m hoping you will have an easier time understanding the examples on the Neat homepage.

What I like

Neat’s emphasis on semantic markup may seem trivial (or even pedantic) at first, but I find that it makes it much easier for me to read and understand my own markup days or weeks after I wrote it. My tags have class names like “header”, “footer”, and “posts”, and this makes it easy to track down and read the corresponding styles. Using my browser’s developer tools, I can go to a tag and immediately determine whether a sitewide style definition is causing something to break (and then easily fix it).

I also appreciate how Neat offers responsive design without requiring any Javascript.

Lastly, I like the fact that Neat can do pretty much everything Bootstrap’s grid system can, while being small and lightweight.

What I Don’t Like

Unlike Bootstrap, Neat makes you earn your responsive layout. You are responsible for managing everything regarding how it behaves, and there are a few problems with this. Firstly , it isn’t easy to understand at first. Secondly, if you aren’t a veteran web designer, you probably have no idea where to start when it comes to defining breakpoints (though in the next post we will see how this can be mitigated).

The Verdict

Neat has a high learning curve, but its approach to grid layouts and responsive design allows for a lot of control without sacrificing elegance. It isn’t easy, but it is worth the time investment.

In the next post in this series, we will play with Bitters, the third member (and final SASS library) in the Bourbon family,

Update - A day after writing this post, I checked out the documentation for the latest version of Bootstrap. It turns out that it too now supports semantic grids by providing LESS-based mixins. This makes Neat a lot less unique among the competition, though I still think it to be worthwhile. I’ll go into more detail why in the conclusion of this series.