Understanding Spread

Most of susy-sass3 is easy to reason about: a column is a column, a gutter is a gutter. Spread is the one setting that regularly surprises people, because it decides a question that has no single “obvious” answer — when you span several columns, how many gutters come along for the ride?

This page explains spread from the ground up, with worked examples. Once it clicks, the rest of the grid math is straightforward.

Note

susy-sass3 continues the Susy 3 grid API originally designed by Miriam Eric Suzanne and OddBird. The explanation below is written for this fork; the underlying spread behaviour is unchanged from Susy 3.


Columns and the gutters between them

Picture a grid as a row of columns with a gutter between each neighbouring pair. Four columns have three gutters between them:

| col | gap | col | gap | col | gap | col |
  1     .     2     .     3     .     4

That “one fewer gutter than columns” arrangement is the everyday case: it’s how CSS grid tracks work, and how most margin-based grid systems behave. So when you ask for a span of three columns, the natural width is three columns plus the two gutters trapped between them — and nothing on the outside.

That default is what susy-sass3 calls a narrow spread.


The three spreads

Spread is simply a count of how many gutters a span includes relative to its column count. There are three values:

narrow

Gutters only between the columns — one fewer gutter than columns. This is the default, and matches how native CSS grids behave.

wide

The same number of gutters as columns — the internal gutters plus one edge gutter. Handy in padding-based layouts, and for pushing or pulling an element by a column-plus-gutter amount.

wider

A gutter on both outer edges — one more gutter than columns.

A quick way to picture it: narrow grabs the columns and the gaps locked between them, wide also grabs the gap on one side, and wider grabs the gaps on both sides.

narrow:        col gap col gap col
wide:          col gap col gap col gap
wider:     gap col gap col gap col gap

The gutter count, exactly

For a span of n columns, the number of gutters included is:

narrow  ->  n - 1
wide    ->  n
wider   ->  n + 1

So a 3-column span includes 2 gutters when narrow, 3 when wide, and 4 when wider. This is the whole of spread — everything below is just applying that rule.


Worked example

Take the default grid: four equal fluid columns with a gutter one quarter the width of a column.

$susy: (
  'columns': susy-repeat(4),  // 1 1 1 1
  'gutters': 0.25,
  'spread': 'narrow',
  'container-spread': 'narrow',
);

To turn a span into a percentage, susy-sass3 adds up the column units and the gutter units it covers, then divides by the same total for the whole container.

For span(3) (narrow — 2 gutters):

span      = 3 columns + (2 gutters x 0.25) = 3.5
container = 4 columns + (3 gutters x 0.25) = 4.75
width     = 3.5 / 4.75 = 73.68421%

That matches what susy-sass3 returns:

.item { width: span(3); }
// .item { width: 73.68421%; }

Now widen the span by one gutter with span(3 wide) (3 gutters):

span      = 3 + (3 x 0.25) = 3.75
container = 4 + (3 x 0.25) = 4.75
width     = 3.75 / 4.75 = 78.94737%
.push-3 { margin-left: span(3 wide); }
// .push-3 { margin-left: 78.94737%; }

The extra side gutter is exactly why wide is the natural choice for pushing and pulling elements: the offset lines the next element up on the grid.

And span(3 wider) adds the gutter on both edges (4 gutters):

span      = 3 + (4 x 0.25) = 4
container = 4 + (3 x 0.25) = 4.75
width     = 4 / 4.75 = 84.21053%
.item { width: span(3 wider); }
// .item { width: 84.21053%; }

The three spreads on the same span step up by exactly one gutter each — 73.68421% (narrow), 78.94737% (wide), 84.21053% (wider).


Container spread

Spread has a twin: container-spread. It works the same way, but applies to the context — the columns you’re measuring against — rather than the span itself.

  • spread sets the gutters at the edges of your element.

  • container-spread sets the gutters at the edges of the container the element lives in.

In the example above, the container = 4.75 figure used the default narrow container-spread (3 gutters for 4 columns). If the container itself carries an edge gutter — say it uses side padding equal to a gutter — set container-spread: 'wide' so the denominator matches reality:

// container-spread: wide  ->  4 gutters
container = 4 + (4 x 0.25) = 5

Getting these two settings right is what keeps nested elements aligned to the same grid as their parent. When spans don’t line up the way you expect, spread and container-spread are the first place to look.


Setting spread

Set either value globally in $susy, in a per-call $config map, or inline in the shorthand with the narrow / wide / wider keywords:

// global default
$susy: ('spread': 'wide');

// per span, via shorthand
.a { width: span(3 wide); }        // span spread
.b { width: span(3 of 12 wide); }  // container spread (after "of")

See spread and container-spread in the settings reference for the formal definitions.