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:
narrowGutters only between the columns — one fewer gutter than columns. This is the default, and matches how native CSS grids behave.
wideThe 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.
widerA 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.