Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
A pragmatic, responsive, flexible, liquid CSS grid system using Compass, SASS, and Modernizr
branch: develop

This branch is 3 commits behind phil-quinn:develop

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
javascript
scss
.gitignore
README.markdown
config.rb
index.html

README.markdown

Welcome to the Grass Framework

A pragmatic, responsive, flexible, liquid CSS grid system using Compass, SASS, and Modernizr.

Goals

We needed a css grid framework to support our newer mobile-friendly projects. After reviewing a whole bunch of excellent solutions, we ended up creating our own.

The goal of this framework is to allow for flexible CSS grids that:

  • Support the CSS Flexible Box Layout Module if available
  • Fall back to normal, static grid widths if not
  • Can choose NOT to use flexbox if desired
  • Support media queries for different grid layouts, if available
  • Support sub grids
  • Maintain consistent gutter widths, even in sub grids
  • Works with Compass and SASS, our CSS pre-processor of choice
  • Works with CSS3 PIE

Approach

We realized that we only needed to support flexbox on modern browsers, but also needed a fall back for non-flexbox friendly browsers like IE. We also needed a solution that would display something more reasonable than the bare minimum to browers that don’t support media queries.

Some of the decisions we made were:

  • To build on the great work at 320 and up for media query support and basic mobile philosophy
  • To use a negative left margin apporach to the non-flexbox grid for better legacy browser and PIE support
  • To leverage Compass and SASS as much as possible
  • To compromise and usa a “row” function, so we could support better sub grids.

Getting started

First off, you need to be using the SASS CSS pre-processor. You will also need to use Compass, which is a collection of pre-made SASS mixins and helper functions. We’ll also be relying on Modernizr to help us figure our what browsers can support what grid technologies.

We’re going to assume you already know how to work with Modernizr, SASS and Compass. If you don’t, you will want to familiarize yourself with those packages first.

Basic usage

Grass tries to use the flexible box model if it can. It relys on Modernizr to decide if your page can support this. So you need to include Modernizr in your document’s head. And if Modernizr decides your browser can’t handle the flexible box model, or you have JS turned off, Grass falls back on a fixed width solution for your grid.

Let’s set up a simple, three column layout. Here’s the HTML we’re going to add our grid to:

<html>
    <head>
        <title>Simple Three Column Example</title>
        <link rel="stylesheet" href="css/styles.css" />
        <script src="javascript/modernizr-2.6.1.js"></script>
    </head>
    <body>
        <div class="row">
            <div class="left-column">
                <p>Left Column</p>
            </div>
            <div class="middle-column">
                <p>Middle Column</p>
            </div>
            <div class="right-column">
                <p>Right Column</p>
            </div>
        </div>
    </body>
</html>

Let’s assume we’re making a new SASS/Compass stylesheet. We’ll call it styles.scss.

Here's our imaginary file structure:

example.html            <- our HTML page
config.rb               <- SASS config file
javascript/             <- where your javascripts live
    modernizr-2.6.1.js  <- Modernizr
css/                    <- where SASS will put our CSS
    styles.css          <- generated by SASS
scss/                   <- our SASS files
    partials/           <- partials and includes
        _grid.scss      <- Grass grid system
    styles.scss         <- our custom styles

First you would import Compass’ CSS3 module, and our _grid.scss partial into your SASS project, where you want to start using the grid framework.

@import "compass/css3";
@import "partials/grid";

Compass’ compass/css3 module makes sure that we have access to the Compass mixins for the flexible box model.

Grass’ _grid.scss is typically imported from your partials folder, usually as-is.

Now you need to define your grid. Let's setup a basic 24 column grid, with 30px wide columns, and 10px of gutter between columns. That will give us a 950px wide page.

$column-width: 30px;
$gutter-width: 10px;
$columns: 24;

If you don’t set these, Grass will use it’s own defaults:

$column-width: 60px !default;
$gutter-width: 20px !default;
$columns: 12 !default;

Now we can start applying the styling. One of the comprimises we have to deal with in order to have our system fall back to a static grid system if the flexible box model is not available, is that we have to set up a “row” div for our columns. In our case, we’ll use the .row div.

Next we set up the columns. If the row that the columns are in spans all the grid system's columns (in our case 24) then you can just tell each column how many grid units wide it needs to be.

.row {
    @include row();

    .left-column {
        @include column(4);
    }

    .middle-column {
        @include column(12);
    }

    .right-column {
        @include column(6);
    }
}

Ta da! We're done.

Nested Grids

Grass can nest grids inside other grids. And when we do this, it will keep the gutter widths consistent, even when it's flexible.

Here's a new HTML page:

<html>
    <head>
        <title>Simple Nested Example</title>
        <link rel="stylesheet" href="css/styles.css" />
        <script src="javascript/modernizr-2.6.1.js"></script>
    </head>
    <body>
        <div class="row">
            <div class="left-column">
                <p>Left Column</p>
            </div>
            <div class="middle-column">
                <div class="middle-row">
                    <div class="middle-left">
                        <p>Middle Left</p>
                    </div>
                    <div class="middle-right">
                        <p>Middle Right</p>
                    </div>
                </div>
            </div>
            <div class="right-column">
                <p>Right Column</p>
            </div>
        </div>
    </body>
</html>

Let's assume we're using the same grid definitions as before. We can nest another row inside our .middle-column div, and put two columns inside it. The only complication is that we need to pass in the number of columns that our parent row uses, so that Grass can calculate the widths and ratios correctly. This gets passed in as a second parameter to the @column mixin.

So for a 6 unit column inside a 12 unit row, you would use this:

@import column(6,12);

Here's the new, nested SCSS.

.row {
    @include row();

    .left-column {
        @include column(4);
    }

    .middle-column {
        @include column(12);

        .middle-row {
            @include row();

            .middle-left {
                @column(6,12);
            }

            .middle-right {
                @column(6,12);
            }
        }
    }

    .right-column {
        @include column(6);
    }
}

Fixed Width Columns

Sometimes you want one or more of your columns to stay a fixed width, while the other columns can stretch. You can do that by passing true as a third parameter to column include to tell it to not allow that column to flex. This means you have to pass all three parameters, even if your row is full width.

Using our first example, if we wanted the left and right columns to be fixed, we’d do this:

.row {
    @include row();

    .left-column {
        @include column(4,24,true);
    }

    .middle-column {
        @include column(12,24,true);
    }

    .right-column {
        @include column(6,24,true);
    }
}

Responsive grids

You can redefine the grid variables at any time, or even pass them through to the various functions. As long as you’re careful with the specificity of your selectors, you can redefine your grid to your heart’s content. Or demo page is an example of that.

Sometimes you will need to turn off column or row settings to change up your grid. You can do that by passing false to either the row or column includes.

@include row(false);
@include column(false);

Setting a max-width on a grid

You may not want your grid to be stretchy forever. You can put a cap on it with the “grid-width” include. Typically, you apply this to a div that contains your whole page and it caps your page at the width of the current grid definitions.

So for this HTML:

<html>
    <head>...</head>
    <body>
        <div class="page-area">
            <div class="row">
                <div class="left-column">
                    <p>Left Column</p>
                </div>
                <div class="right-column">
                    <p>Right Column</p>
                </div>
            </div>
        </div>
    </body>
</html>

You could set the max-width of the page up like this:

@import "compass/css3";
@import "partials/grid";

$column-width: 30px;
$gutter-width: 10px;
$columns: 24;

.page-area {
    @include grid-width(true);
    margin: 0 auto;
    .row { ... }
}

This would make the .page-area max out at the full grid width of 950px.

If you want to assign an arbitrary max-width, that’s different than the calculated one, you can. Although the fall-back non-flexbox version will still use the normal calculated grid system width.

@include grid-width(1024px);

If you don’t pass in true or a width, grid-width will set the width of the div to the calculated grid width for fallback browsers, but set it to 100% for flexbox capable browsers.

@include grid-width();

Includes & Parameters

Here is a breakdown of the includes and parameters that come with Grass.

Grass defaults which you can override

/* Grass defaults */
$column-width: 60px !default;   // single grid unit
$gutter-width: 20px !default;   // space between units
$columns: 12 !default;          // total grid units across
$use-flexbox: true !default;    // if true, use flexbox if avaiable
$grid-debug: false !default;    // if true, outputs simple debug info

Mixins

@include grid-width()

// flexbox max-width set to 100%, fallback set to calculated grid width
@include grid-width();

// flexbox max-width and fallback set to calculated grid width
@include grid-width(true);

// flexbox max-width set to 1024px, fallback set to calculated grid width
@include grid-width(1024px);

@include row()

@include row();         // establish row
@include row(false);    // turn off row

@include row()

@include column(3);         // 3 unit column, full grid-width row
@include column(3,6);       // 3 unit column inside a 6 unit row
@include column(3,6,true);  // fixed width 3 unit column inside a 6 unit row
@include column(false);     // turn off column settings

@include column-classes()

This function builds a bunch of pre-made column classes, like more traditional grid systems. If you just call it without any parameters, it will produce a set if classes prefixed with .cols- for all the possible unit widths in your grid settings.

Example:

$column-width: 60px;
$gutter-width: 20px;
$columns: 12;

@include column-classes();

Produces the following CSS classes you can use:

.cols-1 {...}
.cols-2 {...}
.cols-3 {...}
.cols-4 {...}
.cols-5 {...}
.cols-6 {...}
.cols-7 {...}
.cols-8 {...}
.cols-9 {...}
.cols-10 {...}
.cols-11 {...}
.cols-11 {...}
.cols-12 {...}
Something went wrong with that request. Please try again.