Want to see the full-length video right now for free?
Sign In with GitHub for Free AccessNeat is a lightweight, open source fluid grid framework built on top of Sass and
Bourbon with an emphasis on flexibility and ease of use. It keeps all of the
presentation code in the CSS, keeping classes like .col-sm-4 .col-lg-8
out of
the HTML. Instead of prescribing class names, Neat allows the developer to
define all of the classes which allows for much more semantic markup, like
.sidebar
instead of .col-sm-3
.
There are more detailed instructions in the Neat README.
gem 'neat'
bundle install
application.scss
, after Bourbon: @import "bourbon";
@import "neat";
// Other stylesheets go after bourbon and neat
@import "users";
The first thing to do with Neat is establish the container that the grid will
sit within. We do that with the outer-container
mixin, which centers the
element it's targeting, clears its floats, and sets its max-width
.
To set the max-width
to 1920px:
@import outer-container(1920px);
Note that this is the maximum width, not its absolute width. Neat is a fluid grid and is responsive to different screen sizes out of the box.
You can also set $max-width: 1920px
in _grid-settings.scss
.
We recommend creating a _grid-settings.scss
file for Neat specific settings.
Make sure to import it right before importing Neat:
@import "bourbon";
@import "grid-settings";
@import "neat";
@import "users";
In your newly created _grid-settings.scss
, import neat-helpers
if you are
planning to use the new-breakpoint()
mixin, then define your new variables:
@import "neat-helpers";
// Define grid setting variables, or don't specify anything and use the
// defaults
$column: 90px;
$gutter: 30px;
$grid-columns: 12;
$max-width: 1300px;
// Create screen size variables
$medium-screen-width: 600px;
$large-screen-width: 900px;
// Define your breakpoints (we'll touch on this later)
$small-screen: new-breakpoint(max-width $medium-screen-width 4);
$medium-screen: new-breakpoint(max-width $large-screen-width 8);
A 12-column grid is very common because it's evenly divisible by 2, 3, 4 and 6, which gives you a lot of flexibility to split up your layout.
With development, there are best practices for organizing modules and sections of code. When designing for the web, a grid system can help organize what's on the page. Grids are great for developers and users alike. They create consistency and allow the user to become familiar with the interface. Note that grids don't always need to be rigid or remain unbroken. Think of them as an aid that creates a great starting point for your layout.
span-columns
Now we can make our grid using the span-columns
mixin.
If we have a 12 column grid (the default), and want our element to take up half of the width:
.my-element {
@include span-columns(6);
}
To work with nested columns (for example, having a 2-column element within a
6-column element), pass the number of columns of the parent to the
span-columns
mixin.
We could start a new 12-column grid, but that child grid would be very slightly (but perceptibly) misaligned with the parent grid. Instead, we should use Neat's built-in nesting features.
SCSS:
.my-element {
@include span-columns(6);
}
.my-element-child {
@include span-columns(2 of 6);
}
Generated CSS:
.my-element {
display: block;
float: left;
margin-right: 2.35765%;
width: 48.82117%;
}
.my-element:last-child {
margin-right: 0;
}
.my-element-child {
display: block;
float: left;
margin-right: 4.82916%;
width: 30.11389%;
}
.my-element-child:last-child {
margin-right: 0;
}
shift
Another common mixin is shift
. This allows for spacing around columns that
stays within our grid. Let's say we have content that we only want to span 8
columns (while still inside our 12 column grid from before).
We can start with this:
.skinny-element {
@include span-columns(8);
}
This would create the correct size column, but it would be floated and aligned all the way to the left. To push it back to center:
.skinny-element {
@include span-columns(8);
@include shift(2); // (12 - 8) / 2
}
Beyond simple grids, Neat has useful functions and mixins for responsive design. It's a flexible, responsive grid framework, so it can target specific screen breakpoints. For example, on a phone you might not need 12 columns. You could use, say, 6 columns for a phone and increase it up to 12 columns on desktop.
We already showed the new-breakpoint()
function in the _grid-settings.scss
file. This allows us to store a media query in a variable to use in our grid
system. (You can learn more about mobile-first design and breakpoints in our
Weekly Iteration video on Responsive
Design.)
To use a breakpoint in a media query (in this case, making a .card
half width
at the $tablet-up-breakpoint
:
// _grid-settings.scss
$grid-columns: 8;
$medium-screen: 600px;
$large-screen: 900px;
// Use 8 columns when screen is >600px wide
$medium-screen-up: new-breakpoint(min-width $medium-screen 8);
// Use 12 columns when screen is >900px wide
$large-screen-up: new-breakpoint(min-width $large-screen 12);
We set $grid-settings
to 8 so that if we don't specify a breakpoint, we use 8
columns, but can use 12 on large screens using the $large-screen-up
breakpoint.
.card {
@include fill-parent;
@include media($medium-screen-up) {
// span 4 of the 8 columns when the screen is >600px
@include span-columns(4);
}
@include media($large-screen-up) {
// span 8 of the 12 columns when the screen is >900px
@include span-columns(8);
}
}
omega
One useful pattern is using omega()
to create multiple rows of columns without
needing to wrap each with a row()
element. This is great for things like photo
grids, lists of cards or products, or any element where you'd like to remove the
gutter margin. We can use omega
to remove the right margin on every 3rd
element (to make 3-element-wide rows). Without omega
, the 3rd element is just
barely too large to fit and will be bumped to the next row.
SCSS:
.product {
@include span-columns(4 of 12);
@include omega(3n);
}
Generated CSS:
.product {
float: left;
display: block;
margin-right: 2.12766%;
width: 31.91489%;
}
.product:last-child {
margin-right: 0;
}
.product:nth-child(3n) {
margin-right: 0;
}