/lost

SCSS, LESS, and Stylus fractional grid system built with calc() by the guy who built Jeet. Supports masonry, vertical, and waffle grids.

Primary LanguageCSSMIT LicenseMIT

Lost Grid is a grid system for SCSS or Stylus. It is built upon years of studying and building grid systems with tons of community feedback.

It makes use of calc() to create stunning grids based on fractions you define.

I can tell you with no ego, this is my finest grid.

See for yourself! Fork a demo on CodePen and follow along: SCSS, LESS, or Stylus

Table of Contents

Better than X

Lost is better than any grid system out there and can prove it.

Feature Lost Bootstrap Foundation Jeet Neat Susy
Responsive
Small learning curve
Easy-to-implement
Works with Masonry
Terse markup
On-the-fly grids
Clean markup
Real gutters
Stylus support
LESS support
No Additional Ratio Context
Consistent Gutters on All Sides
Lightweight
Vertical Grids
Waffle Grids
Fixed Gutters
Flexbox Grids

If you notice anything in this table is incorrect or unfair, please don't hesitate to open an issue.

Getting Started

Installation

Installing Lost is easy. Just bower install lost-grid in your project directory, then add @import '/bower_components/lost-grid/PREPROCESSOR/lost.styl' to the top of your preprocessor stylesheet.

 

Basic Columns

To create a basic horizontal grid, just insert some columns into any element like so and pass a fraction (as a string) to column().

HTML
```html
1 2 3 4
```
SCSS
```scss section { @include clearfix; }

figure { @include column('1/2'); }


<h6 align="right">LESS</h6>
```less
section {
  .clearfix();
}

figure {
  .column(1 of 2);
}
Stylus
```stylus section clearfix()

figure column('1/2')


`clearfix()` is just a [clearfix](http://nicolasgallagher.com/micro-clearfix-hack/) mixin since grid elements are floated. It's a good idea to give this to the element wrapping your grid elements every time.

&nbsp;

##### Centering Elements

You can also make use of the `center()` mixin to assign a `max-width` and `margin: auto` to an element and center it on the page. `clearfix()` will automatically be applied in this case.

<h6 align="right">SCSS</h6>
```scss
section {
  @include center(980px);
}

figure {
  @include column('1/2');
}
LESS
```less section { .center(980px); }

figure { .column(1 of 2); }


<h6 align="right">Stylus</h6>
```stylus
section
  center(980px)

figure
  column('1/2')

 

Controlling Cycle

Every element gets a float: left and margin-right: $gutter applied to them except the last one in the row. Lost will automatically detect the last item in a row (based on the denominator you passed) and apply a margin-right: 0 to it by default.

To override this behavior simply pass a cycle param to your column().

SCSS
```scss figure { @include column('2/4', $cycle: 2); } ```
LESS
```less figure { .column(2 of 4, @cycle: 2); } ```
Stylus
```stylus figure column('2/4', $cycle: 2) ```

 

Nesting

Nesting is simple and requires no extra fractions unlike other preprocessor grid systems.

HTML
```html
a b c c
```
SCSS
```scss figure { @include column('1/2'); } ```
LESS
```less figure { .column(1 of 2); } ```
Stylus
```stylus figure column('1/2') ```

 

Offseting Elements

You can offset columns easily. To offset in the other direction, pass a negative fraction.

HTML
```html
1 2
```
SCSS
```scss figure { @include column('1/3'); &:first-child { @include offset('1/3'); } } ```
LESS
```less figure { .column(1 of 3); &:first-child { .offset(1 of 3); } } ```
Stylus
```stylus figure column('1/3') &:first-child offset('1/3') ```

 

Alignment

Easily align children elements with the align() mixin. It accepts options like top-left, right, center, etc.

HTML
```html
Aligned
```
SCSS
```scss section { @include align; width: 600px; height: 400px; }

figure { width: 100px; height: 100px; }


<h6 align="right">LESS</h6>
```less
section {
  .align();
  width: 600px;
  height: 400px;
}

figure {
  width: 100px;
  height: 100px;
}
Stylus
```stylus section align() width: 600px height: 400px

figure width: 100px height: 100px


&nbsp;

##### Edit Mode

Use the `edit()` mixin at base level to visualize the entire structure of your site, or just specify the areas you're working on. You can pass it any color (pick a darkish one because `edit()` will lighten it).

<h6 align="right">HTML</h6>
```html
<section>
  <figure>1</figure>
  <figure>2</figure>
  <figure>3</figure>
</section>

<section>
  <figure>4</figure>
  <figure>5</figure>
  <figure>6</figure>
</section>
SCSS
```scss section { &:nth-of-type(1) { @include edit; } &:nth-of-type(2) { @include edit(green); } } ```
LESS
```less section { &:nth-of-type(1) { .edit(); } &:nth-of-type(2) { .edit(green); } } ```
Stylus
```stylus section &:nth-of-type(1) edit() &:nth-of-type(2) edit(green) ```

 

Vertical Grids

Once you've mastered the basic horizontal grid system (it shouldn't take long), you can start to make vertical grids that have the same vertical gutters as your horizontal grids. Just use the row() mixin in place of column(). These rows will stretch to fill their container's height, so if you'd like to see them take up the full height of the page, set height: 100% on your container.

No other grid system in the world supports vertical grids.

HTML
```html
1 2 3
```
SCSS
```scss section { height: 100%; }

figure { @include row('1/3'); }


<h6 align="right">LESS</h6>
```less
section {
  height: 100%;
}

figure {
  .row(1 of 3);
}
Stylus
```stylus section height: 100%

figure row('1/3')


&nbsp;

##### Waffle Grids

You can even make a horizontal/vertical grid (a **waffle grid**) which resembles a tic-tac-toe board.

<h6 align="right">HTML</h6>
```html
<section>
  <figure>1</figure>
  <figure>2</figure>
  <figure>3</figure>
  <figure>4</figure>
  <figure>5</figure>
  <figure>6</figure>
  <figure>7</figure>
  <figure>8</figure>
  <figure>9</figure>
</section>
SCSS
```scss section { height: 100%; }

figure { @include waffle('1/3'); }


<h6 align="right">LESS</h6>
```less
section {
  height: 100%;
}

figure {
  .waffle(1 of 3);
}
Stylus
```stylus section height: 100%

figure waffle('1/3')


&nbsp;

##### Flexbox Grids

You can easily change your grids to support Flexbox by altering the global variable: `$flexbox` to `true`. Once you do this, all grids throughout your site will use flexed elements. To make sure they are displayed as flexed elements, you need to wrap them in `flex-container()` or `center()` (which includes `flex-container()` by default).

<h6 align="right">HTML</h6>
```html
<section>
  <figure>1</figure>
  <figure>2</figure>
  <figure>3</figure>
</section>
SCSS
```scss $flexbox: true;

section { @include center(); }

figure { @include column('1/3'); }


<h6 align="right">LESS</h6>
```less
@flexbox: true;

section {
  .center();
}

figure {
  .column(1 of 3);
}
Stylus
```stylus $flexbox = true

section center()

figure column('1/3')


Flexbox offers cleaner output and avoids the use of `clearfix` and other issues with float-based layouts. It also allows you to have elements of even height rather easily, and [much more](https://github.com/philipwalton/flexbugs/issues/32#issuecomment-90789645). The downside is, Flexbox doesn't work in IE9 or below, so keep that in mind if you have a client that needs that kind of support.

Also note that waffle grids work well for the most part, but are somewhat finicky in fringe situations where Flexbox tries to act smarter than it is. All mixins provide a way to disable or enable Flexbox per element with the `flex` parameter.


&nbsp;

##### Masonry Support

Lost supports masonry plugins like [Isotope](http://isotope.metafizzy.co/). To accomplish this we need to change how the margins work. Instead of applying a `margin-right` to everything, we need to apply it to both sides. We've made a couple special mixins to help with this: `masonry-column()` which creates a margin on the left and right of each element it's applied to, and `masonry-wrap()` which wraps your columns and applies a negative margin to the left and right to them to help line them up with containing elements.

<h6 align="right">HTML</h6>
```html
<section>
  <figure>1</figure>
  <figure>2</figure>
  <figure>3</figure>
</section>
SCSS
```scss section { @include masonry-wrap; }

figure { @include masonry-column('1/3'); }


<h6 align="right">LESS</h6>
```less
section {
  .masonry-wrap();
}

figure {
  .masonry-column(1 of 3);
}
Stylus
```stylus section masonry-wrap()

figure masonry-column('1/3')



## Grid Settings

Just set either of these in a settings file after you `@import` Lost and before you use a Lost mixin.

<h6 align="right">SCSS</h6>
- `$gutter: 30px !default;`
- `$rtl: false !default;`

<h6 align="right">LESS</h6>
- `@gutter: 30px;`
- `@rtl: false;`

<h6 align="right">Stylus</h6>
- `$gutter = 30px`
- `$rtl = false`


## Mixin Options

##### `edit()`
Sets a translucent background color to all elements it affects. Helpful while setting up, or debugging, the structure of your site to make sure all items are cleared correctly.

<h6 align="right">SCSS</h6>
```scss
section {
  @include edit(red);
}
LESS
```less section { .edit(red); } ```
Stylus
```stylus section edit(red) ```

 

clearfix()

Clearfix used to clear floated children elements. http://nicolasgallagher.com/micro-clearfix-hack

SCSS
```scss .parent { @include clearfix; .child { @include column('1/2'); } } ```
LESS
```less .parent { .clearfix(); .child { .column(1 of 2); } } ```
Stylus
```stylus .parent clearfix() .child column('1/2') ```

 

flex-container()

Creates a Flexbox container.

  • $direction: row - The flex-direction the container should create. This is typically opposite to the element you're creating so a row() would need flex-container(column).
SCSS
```scss $flexbox: true;

section { @include flex-container(); figure { @include column('1/2'); } }


<h6 align="right">LESS</h6>
```less
@flexbox: true;

section {
  .flex-container();
  figure {
    .column('1/2');
  }
}
Stylus
```stylus $flexbox = true

section flex-container() figure column('1/2')


&nbsp;

##### `center()`
Horizontally center a container element and apply padding to it.

- `$max-size: 1140px` - A max-width to assign. Can be any unit.
- `$pad: 0` - Padding on the left and right of the element. Can be any unit.
- `$flex: $flexbox` - Determines whether this element should use Flexbox or not.

<h6 align="right">SCSS</h6>
```scss
section {
  @include center(900px);
}
LESS
```less section { .center(900px); } ```
Stylus
```stylus section center(900px) ```

 

align()

Align nested elements.

  • $location: middle-center - The position the nested element takes relative to the containing element.
    • reset
    • top-left
    • top-center or top
    • top-right
    • middle-left or left
    • middle-right or right
    • bottom-left
    • bottom-center or bottom
    • bottom-right
  • $flex: $flexbox - Determines whether this element should use Flexbox or not.
SCSS
```scss .parent { @include align(right); width: 600px; height: 400px; .child { width: 300px; height: 150px; } } ```
LESS
```less .parent { .align(right); width: 600px; height: 400px; .child { width: 300px; height: 150px; } } ```
Stylus
```stylus .parent align(right) width: 600px height: 400px .child width: 300px height: 150px ```

 

column()

Creates a column that is a fraction of the size of it's containing element with a gutter. You don't need to pass any additional ratios (fractions) as the grid system will make use of calc(). Note that fractions must always be wrapped in quotes.

  • $fraction: '1/1' - This is a simple fraction of the containing element's width. This must be a string written as a fraction.
  • $cycle: DENOMINATOR - Lost works by assigning a margin-right to all elements except the last in the row. It does this by default by using the denominator of the fraction you pick. To override this default use this param. e.g. column('2/4', $cycle: 2)
  • $gut: $gutter - The margin on the right side of the element used to create a gutter. Typically this is left alone and the global $gutter will be used, but you can override it here if you want certain elements to have a particularly large or small gutter (pass 0 for no gutter at all).
  • $flex: $flexbox - Determines whether this element should use Flexbox or not.
SCSS
```scss figure { @include column('1/3'); } ```
LESS
```less figure { .column(1 of 3); } ```
Stylus
```stylus figure column('1/3') ```

 

row()

Creates a row that is a fraction of the size of it's containing element with a gutter. You don't need to pass any additional ratios (fractions) as the grid system will make use of calc(). Note that fractions must always be wrapped in quotes.

  • $fraction: '1/1' - This is a simple fraction of the containing element's height. This must be a string written as a fraction.
  • $gut: $gutter - The margin on the bottom of the element used to create a gutter. Typically this is left alone and the global $gutter will be used, but you can override it here if you want certain elements to have a particularly large or small gutter (pass 0 for no gutter at all).
  • $flex: $flexbox - Determines whether this element should use Flexbox or not.
SCSS
```scss figure { @include row('1/3'); } ```
LESS
```less figure { .row(1 of 3); } ```
Stylus
```stylus figure row('1/3') ```

 

waffle()

Creates a block that is a fraction of the size of it's containing element with a gutter on the right and bottom. You don't need to pass any additional ratios (fractions) as the grid system will make use of calc(). Note that fractions must always be wrapped in quotes.

  • $fraction: '1/1' - This is a simple fraction of the containing element's width/height. This must be a string written as a fraction.
  • $cycle: DENOMINATOR - Lost works by assigning a margin-right/bottom to all elements except the last row (no margin-bottom) and the last column (no margin-right). It does this by default by using the denominator of the fraction you pick. To override this default use this param. e.g. waffle('2/4', $cycle: 2)
  • $gut: $gutter - The margin on the right and bottom side of the element used to create a gutter. Typically this is left alone and the global $gutter will be used, but you can override it here if you want certain elements to have a particularly large or small gutter (pass 0 for no gutter at all).
  • $flex: $flexbox - Determines whether this element should use Flexbox or not.
SCSS
```scss figure { @include waffle('1/3'); } ```
LESS
```less figure { .waffle(1 of 3); } ```
Stylus
```stylus figure waffle('1/3') ```

 

offset()

Margin to the left, right, bottom, or top, of an element depending on if the fraction passed is positive or negative. It works for both horizontal and vertical grids but not both.

  • $fraction: '1/1' - Fraction of the container to be offset. Must be a string.
  • $dir: row - Direction the grid is going. Should be the opposite of the column() or row() it's being used on.
  • $gut: $gutter - How large the gutter involved is, typically this won't be adjusted, but if you have set the elements for that container to have different gutters than default, you will need to match that gutter here as well.
SCSS
```scss .two-elements { @include column('1/3'); &:first-child { @include offset('1/3'); } } ```
LESS
```less .two-elements { .column(1 of 3); &:first-child { .offset(1 of 3); } } ```
Stylus
```stylus .two-elements column('1/3') &:first-child offset('1/3') ```

 

move()

Source ordering. Shift elements left, right, up, or down, by their left or top position by passing a positive or negative fraction.

  • $fraction: '1/1' - Fraction of the container to be shifted. Must be a string.
  • $dir: row - Direction the grid is going. Should be the opposite of the column() or row() it's being used on.
  • $gut: $gutter - Adjust the size of the gutter for this movement. Should match the element's $gut.
SCSS
```scss figure { @include column('1/3'); @include move('1/3'); } ```
LESS
```less figure { .column(1 of 3); .move(1 of 3); } ```
Stylus
```stylus figure column('1/3') move('1/3') ```

 

masonry-wrap()

Creates a wrapping element for working with JS masonry libraries like Isotope. Assigns a negative margin on each side of this wrapping element.

  • $gut: $gutter - How large the gutter involved is, typically this won't be adjusted and will inherit the global $gutter setting, but it's made available if you want your masonry grid to have a special $gut, it should match your masonry-column's $gut.
  • $flex: $flexbox - Determines whether this element should use Flexbox or not.
masonry-column()

Creates a column for working with JS masonry libraries like Isotope. Assigns a margin to each side of the element.

  • $gut: $gutter - How large the gutter involved is, typically this won't be adjusted and will inherit the global $gutter setting, but it's made available if you want your masonry grid to have a special $gut, it should match your masonry-row's $gut.
  • $flex: $flexbox - Determines whether this element should use Flexbox or not.
SCSS
```scss section { @include masonry-wrap; } figure { @include masonry-column('1/3'); } ```
LESS
```less section { .masonry-wrap(); } figure { .masonry-column(1 of 3); } ```
Stylus
```stylus section masonry-wrap() figure masonry-column('1/3') ```

 

get-size()

A function to return the size of a column minus it's gutter if a gutter is assigned. Handy for generating CSS classes.

Note This feature is not currently available in the LESS version. I'm not a fan of LESS but would love a PR.

  • $fraction: '1/1' - This is a simple fraction of the containing element's width. This must be a string written as a fraction.
  • $gut: $gutter - The gutter assigned to this size.
SCSS
```scss [class*="col-"] { float: left; margin-right: $gutter; &:last-child { margin-right: 0; } }

@for $i from 1 through 12 { .col-#{$i} { width: get-size('#{$i}/12'); } }


<h6 align="right">Stylus</h6>
```stylus
[class*="col-"]
  float: left
  margin-right: $gutter
  &:last-child
    margin-right: 0

for $i in 1..12
  .col-{$i}
    width: get-size(s('%s/12', $i))

Usage with Node

  • npm i lost-grid --save-dev
JavaScript
```javascript var fs = require('fs'), stylus = require('stylus'), lost = require('lost-grid');

stylus(fs.readFileSync('./css/style.styl', 'utf8')) .use(lost()) .render(function(err, css){ if (err) return console.error(err); console.log(css); });


<h6 align="right">Stylus</h6>
```stylus
@import 'lost'

$gutter = 20px

figure
  column('1/3')

Example Code

Browser Support

  • calc() grids work perfect on IE9+ with poor support on old Android browsers (calc() browser support).
  • With some polyfills (like the ones included in Boy) Lost works perfect in IE8 as well.

Other Projects

If you like this project then I encourage you to check out a few of my other hand-selected projects.

  • Boy - A super lightweight, old-browser-friendly, HTML5 boilerplate with tons of features that make it a great start to any project.
  • Typographic - Insanely powerful yet easy-to-use responsive typography. Includes vertical rhythm, font stacks, modular scale, and more.
  • lost-grid.js - A purely JavaScript version of Lost v1. You can create your grid system directly in your markup without ever touching a line of preprocessor code. A pretty cool concept.

Thanks

  • Alex Bass for being my friend during this process and letting me bounce every idea off you.
  • Maria Keller for the amazing logo. Be sure to hire her for all your design and motion graphic needs.
  • Hugo Giraudel for contributions to code quality and for polyfilling Sass.
  • Roman Komarov for helping with Stylus hiccups.
  • Huy Hong for helping with Sass hiccups.
  • Everyone who files an Issue when something isn't working as expected.
  • Everyone who is actually interested in my work on grids.