Flexbox Grid Finesse
Heydon
44515

How would you suggest adding a gutter with this pattern?

A few ideas, but none are ideal… (please tell me I’m missing something obvious here!)

Subtract width from each item

Pros: simple syntax; leans on flexbox features
Cons: takes a bit of maths; loses last-row ‘magic’

If you forget auto-filling the last row, you can do this:

.parent {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.child {
flex-grow: 0; /* Do not grow to fill available free space */
flex-shrink: 0;
flex-basis: calc(25% - 0.75em); /* 4-per-row with 1em gutter */
}

— i.e. subtract an appropriate amount from each item’s width, then let the browser distribute this remainder as space between the items.

Although this is slightly fiddly because the amount to subtract depends on the number per row according to this equation:

gutter_width * (items_per_row – 1 / items_per_row)

e.g. this would give you three-per-row (still with a 1em gutter):

flex-basis: calc(33.33% - 0.667em);

Obviously you could write a SASS mixin for this, but it’d be nice if we didn’t need SASS for a simple grid.

But all the last-row magic in Heydon’s original article goes out the window, because we had to sacrifice flex-grow: 1.

Margin

Pros: retains last-row ‘magic’
Cons: requires a hack; not DRY

Alternatively flex-grow: 1 could be used with a margin-right[1] on each item, but it takes a hack: a negative margin on the left edge of the parent (so the items appear flush with the sides of the container):

.parent {
display: flex;
flex-flow: row wrap;
margin: 0 -1em; /* make room for excess margins */
}
.child {
flex: 1 0 calc(25% - 1em);
margin-left: 1em;
}

[1] Or margin-right. Or half on each, but it’s easier to just do one or other.

Again, you need to subtract some width from each item (otherwise fewer items will fit per row) — but the maths is easier: you just subtract the gutter width. But now the gutter width is defined in three separate places.

Because of the negative margin trick, a background on .parent will appear to extend out of the container to the left, which isn’t great. Plus any non-grid items (i.e. without the child class) added to .parent will need to take the negative margin into account… maybe an edge case — and one which applies to most pre-flexbox grid systems — but removes a bit of flexibility.

Others

There are probably some other ways, but I suspect they’re either just as complicated or have more caveats (e.g. markup changes). If so, I’m sad this is isn’t a straightforward thing to do. If not, I’ll be very happy to be shown the light.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.