Skip to content

Instantly share code, notes, and snippets.

@edwardoriordan
Forked from mirisuzanne/tutorial.mkdn
Created August 22, 2011 22:20
Show Gist options
  • Save edwardoriordan/1163794 to your computer and use it in GitHub Desktop.
Save edwardoriordan/1163794 to your computer and use it in GitHub Desktop.
A new Susy tutorial

Susy Tutorial

For this tutorial I'm assuming you are already comfortable with CSS, Sass (I'll use the SCSS syntax) and Compass. Please get set up with each one of those before attempting to use Susy. Sass and Compass both have their own setup instructions and tutorials that you can use.

What Susy Does

CSS Systems

Susy is a compass plugin to implement one part of Natalie Downe's CSS Systems: the grid. Natalie's suggestion is simple: for the most responsive layout and the easiest maintenance, grids should be fluid on the inside and elastic on the outside. Here's how that might look in CSS:

#container {  
  width: 59em;       /* 12 columns, 4em wide with 1em gutters between */  
  max-width: 100%;  
}

.column {  
  width: 6.779%;          /* 4em column */  
  margin-right: 1.695%;   /* 1em gutter */  
}

Code like this will expand or contract based on user font sizes and collapse gracefully at smaller window sizes. We can also change the entire grid by adjusting one number. Do you want to make it larger? Replace 59em with 82em. Fixed? Replace 59em with 960px. Fluid? Replace 59em with 87%. In each case, the fluid grid will adjust to match the outer shell.

Target / Context = Multiplier

Having css that allows us to be 'fluid on the inside, elastic on the outside' is not all that hard. You set the width of the container in whatever way you like (%, em, px, etc.) and set the columns on the inside of in %. Want an even 4 column split set them all to 25%. If, however, you need it all to correspond to a grid with gutters you need to start doing some math. And if you want to be able to subdivide those columns into more columns and stick to your grid? Well that is a lot of repetitive boring maths.

That's why I built Susy, and that is all that Susy does. Lucky for us, it all boils down to one simple equation:

target / context = multiplier

You might need to use that math to adjust your font size from 12px to 16px using relative sizes:

16px [target] / 12px [context] = 1.33333 [multiplier]

Knowing that, you can write code like:

font-size: 1.33333em;

or:

font-size: 133.333%;

Susy uses that same equation to handle everything about your grid. Columns and gutters are simple a percentage of the container. Nested columns are simply a percentage of their parent column. And so on.

Not a Framework

Susy doesn't make any effort to cover all your needs. There is no styling help, and no attempt to push you in a certain direction. Susy was built to handle one repetitive task and handle it well. It doesn't care how you work or what styles you want over top of the grid. It's built for flexability - a simple tool that you can use to create the base structure of your site. Nothing more.

There's no magic here, just CSS. Susy can't do anything that CSS can't do. It can just write some of that CSS automatically. The output from Susy is almost entirely width, margin and padding properties.

Building a Susy Grid

Step 1: Declare Your Grid

In the provided '_base' sass partial you have this:

$total-cols             : 12;  
$col-width              : 4em;  
$gutter-width           : 1em;  
$side-gutter-width      : $gutter-width;  

$total-cols is the number of columns in your grid, $col-width is the width of any one column, $gutter-width is the space between columns, and $side-gutter-width is the space between your outer columns and the edge of the container. Set each one to match your desired grid. The default above is elastic, but what if we want something else?

// Fixed Grid

$total-cols             : 6;  
$col-width              : 150px;  
$gutter-width           : 20px;  
$side-gutter-width      : 5px;

// Fluid Grid

$total-cols             : 24;  
$col-width              : 3%;  
$gutter-width           : 1%;  
$side-gutter-width      : 0%;

Step 2: Apply Your Grid

There are four main mixins required in the use of Susy: 'container', 'columns', 'alpha' and 'omega'. I'm only using non-semantic markup in these examples so that you can see what I am doing. Use the markup that you like. I'm also assuming the default elastic 12-column grid.

// Two-Sidebar Example SCSS

#container {  
  @include container;  
}

.left-sidebar {  
  @include columns(3);  
  @include alpha;  
}

.main-content {  
  @include columns(6);  
}

.right-sidebar {  
  @include columns(3);  
  @include omega;  
}

Compiled into CSS, we get the following (along with some clearfix and IE hasLayout help):

#container {  
  margin: auto;               /* centering */  
  width: 61em;                /* grid container size */  
  max-width: 100%;            /* responsive layout */  
}

.left-sidebar {  
  float: left;                /* float left */  
  width: 22.951%;             /* span 3 columns */  
  margin-right: 1.639%;       /* right gutter */  
  margin-left: 1.639%;        /* left side gutter */  
}

.main-content {  
  float: left;                  
  width: 47.541%;             /* span 6 columns */  
  margin-right: 1.639%;       
}

.right-sidebar {  
  float: right;               /* float right */  
  width: 22.951%;             /* span 3 columns */  
  margin-right: 1.639%;       /* right side gutter */  
}

Making Complex Grids

Nesting Columns

There are many ways to get more complex with Susy, but nesting columns inside other columns is probably the most common. And it's easy if you understand how Susy handles context. Once you start nesting columns, you need to know the width of the parent column in order to determine the relative width of the child. I've written a more detailed context demo that I recommend. This can be the trickiest part to understand. But here's how we might use it:

.main-content {  
  @include columns(6);      /* this will be our context for items nested inside it */
  
  .main-left-half {  
    @include columns(3,6);    /* 3 columns out of 6 */  
                              /* we don't need alpha when we are nested */  
  }
  
  .main-right-half {  
    @include columns(3,6);  
    @include omega(6);        /* we do need omega, this time with context */  
  }
}

That's all it takes. Here's the result for our two nested classes:

.main-content .main-left-half {  
  float: left;                  
  width: 48.276%;           /* 3 columns out of 6 */  
  margin-right: 3.448%;     /* right gutter */  
}

.main-content .main-right-half {  
  float: right;                  
  width: 48.276%;           /* 3 columns out of 6 */  
  margin-right: 0;          /* no right gutter */  
}

Prefix, Suffix and Shortcuts

Susy also provides some shortcuts for adding blank columns before and after the column you are working on. They work exactly like 'columns', but they add to the left and right padding of the element you are working on:

.column-with-padding {  
  @include columns(3,6);  
  @include prefix(1,6);  
  @include suffix(2,6);  
  @include omega(6);  
}

That will give us a width of 4 columns, with 1 column padding on the left and 2 columns padding on the right, all floated left, with no right gutter. We just used all six columns. Let's clean that up with some shortcuts.

The 'pad' shortcut allows us to add both prefix and suffix. The 'full' shortcut replaces columns, alpha and omega when we plan to span the full context:

.column-with-padding {  
  @include full(6);  
  @include pad(1,2,6);  
}

The only change in output is that Susy wont bother setting a width and floating it left. Why should we? The width will happen automatically, and the float isn't needed.

Accessing The Math with Functions

You can also access the math more directly and use it wherever you want with Susy's functions. The functions work exactly like their mixin counterparts, but only return the numbers:

.functions {  
  width: columns(3);  
  margin-right: gutter();  
  margin-left: columns(4) + gutter() + side-gutter();  
  padding-right: columns(1);  
}

Visualizing Your Grid

Susy includes a mixin to show you the grid as a background-image on your container element:

.container {  
    @include container;  
    @include susy-grid-background;  
}

Right-to-Left or Multi-Direction Grids

Susy now handles grids going in any direction, even multiple directions in one site. The simplest option is to change the $from-direction setting in your 'base' sass file. By default it is set to 'left'. Change that, and everything in Susy should just work:

$from-direction: right;

Now alpha columns will be on the right, and omega columns on the left. Gutters will be on the left of columns, etc. Everything works the same.

If you need to override the direction for specific widgets, all the affected mixins can be sent a final $from argument. Those mixins include columns, alpha, omega, prefix, suffix and pad:

.rtl-widget {  
  @include columns(3,6,right)  
  @include prefix(1,6,right)  
  @include omega(6,right)  
}
@mirisuzanne
Copy link

incorporated some of your ideas into the original. let me know what you think.

@pablohart
Copy link

Thanks, this is helpful. Is there a concept in Susy that uses margin instead of padding for prefix/suffix? For example, in Blueprint, they use prepend/append for padding and push/pull for margin. Any help you can give is appreciated!

@mirisuzanne
Copy link

mirisuzanne commented Sep 16, 2011 via email

@bdhumb
Copy link

bdhumb commented Apr 3, 2013

Running the samples here with the include columns(3) etc. results in error messages like Undefined mixin: 'columns'. I think you're meant to use span-columns in newer versions of susy. Similarly I don't know if you can use alpha and omega as mixins any more. I write this for the benefit of anyone stumbling across this via web searches and also for the benefit of the author(s) to change it or at least change the title from "A new Susy tutorial".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment