Grid & Container
Which grid
Sulphuris ships two. .grid + .col-* is the default โ flexbox, twelve columns, responsive widths, offsets and gutters. Use it for page layout and anything column-shaped.
Reach for native CSS grid (.d-grid + .grid-cols-* + .gap-*) when you need two-dimensional control: equal-height rows, row templates, item spanning.
They compose โ a .col-6 can be a .d-grid.
Container
.container centers content with max-width: 105rem (1680px at the default root โ the same width as the xxl breakpoint, which is why the two convert together) and horizontal padding that switches at the lg breakpoint:
| Viewport | Padding (each side) |
|---|---|
below lg |
1rem (16px) |
lg and up |
3.5rem (56px) |
<div class="container">โฆ</div>
Grid row
.grid is a display: flex; flex-flow: row wrap wrapper. It has no gutter by itself.
Add .grid-gutter to apply negative side margins that cancel the column padding, producing consistent gutters between columns without extra math on the outside edges:
| Viewport | Column padding (each side) | Row negative margin (each side) |
|---|---|---|
below lg |
0.5rem (8px) | -0.5rem |
lg and up |
1rem (16px) | -1rem |
The full gutter values are $grid-gutter-mobile: 16px and $grid-gutter: 32px โ each side gets half. The halving happens in px and only the finished value converts to rem, so the row's negative margin and the column's padding can never round to different units.
.grid-gutter and .container can be combined on the same element. When combined, the padding accounts for both the container offset and the half-gutter:
<div class="grid grid-gutter container">
<div class="col-12 col-md-6 col-lg-4">โฆ</div>
<div class="col-12 col-md-6 col-lg-4">โฆ</div>
<div class="col-12 col-md-6 col-lg-4">โฆ</div>
</div>
Columns โ .col-N
12 columns. Width is a percentage: 100 / 12 * N.
.col-1 โ 8.333โฆ%
.col-2 โ 16.666โฆ%
.col-3 โ 25%
.col-4 โ 33.333โฆ%
.col-6 โ 50%
.col-8 โ 66.666โฆ%
.col-9 โ 75%
.col-12 โ 100%
Classes exist for every integer 1โ12.
Responsive columns โ .col-{bp}-N
Each column class has a breakpoint variant that applies at min-width. Breakpoints:
| Name | Min-width |
|---|---|
sm |
26.25rem (420px) |
md |
48rem (768px) |
lg |
64rem (1024px) |
xl |
85.375rem (1366px) |
xxl |
105rem (1680px) |
The base .col-N (no breakpoint) applies at all widths. Layer responsive classes on top for wider viewports:
<!-- Full width on mobile, half at md, third at lg -->
<div class="col-12 col-md-6 col-lg-4">โฆ</div>
Full responsive example โ the twelve columns are drawn behind it, so press the width buttons and watch each card land on twelve, six and four of them:
<div class="grid grid-gutter container">
<div class="col-12 col-md-6 col-lg-4"><div class="bg-gray-200 p-16">Card A</div></div>
<div class="col-12 col-md-6 col-lg-4"><div class="bg-gray-200 p-16">Card B</div></div>
<div class="col-12 col-md-12 col-lg-4"><div class="bg-gray-200 p-16">Card C</div></div>
</div>Offsets โ .col-offset-N
Pushes a column right by adding margin-left as a percentage of the parent. Range: 0โ11.
.col-offset-0 โ margin-left: 0%
.col-offset-1 โ margin-left: 8.333โฆ%
.col-offset-6 โ margin-left: 50%
.col-offset-11 โ margin-left: 91.666โฆ%
Responsive variants follow the same pattern: .col-offset-{bp}-N.
<div class="grid grid-gutter">
<div class="col-6 col-offset-3"><div class="bg-gray-200 p-16">Centered 6-column block</div></div>
</div>.grid-reverse
Add .grid-reverse to a .grid row to set flex-direction: row-reverse. When .grid-reverse is present, offset classes switch from margin-left to margin-right, so offsets keep working visually in the reversed direction.
Flex-only โ flex-direction does nothing on a .d-grid container. Native grid reverses with direction: rtl or explicit line placement.
<div class="grid grid-gutter grid-reverse">
<div class="col-4 col-offset-2"><div class="bg-gray-200 p-16">Pushed from the right</div></div>
</div>Max-width columns โ .col-N-max
.col-N-max caps an element's max-width to N columns' worth of the largest breakpoint (xxl, 1680px), accounting for container offsets and gutters. Range: 1โ11 (.col-12-max is not generated; use the container's full width instead).
The value is computed in px from the max breakpoint width minus container padding on both sides plus one gutter unit, scaled by the column fraction, then converted once at the end:
desktop: (1680 - 56ร2 + 32) ร (N/12) โ 1600 ร (N/12)
mobile: (1680 - 16ร2 + 16) ร (N/12) โ 1664 ร (N/12)
Examples (desktop):
.col-6-max โ max-width: 50rem (800px)
.col-4-max โ max-width: ~33.3rem (~533px)
.col-3-max โ max-width: 25rem (400px)
Use .col-N-max when you want an element to grow freely on small screens but never exceed the proportional column width at full desktop scale.
<img class="col-6-max" src="photo.jpg" alt="">
Native CSS grid
Separate from the 12-column flex system above, these utilities drive a real display: grid container.
| Class | CSS |
|---|---|
.d-grid |
display: grid |
.d-inline-grid |
display: inline-grid |
Every class in this section spells out the axis as column / row, never col โ matching .flex-column in Flexbox, and keeping the flex grid's .col-* namespace clear.
All of them generate responsive variants, with the breakpoint before the value: .grid-cols-md-3, .grid-column-span-lg-4, .grid-flow-md-column.
Track templates
| Class | CSS |
|---|---|
.grid-cols-{n} |
grid-template-columns: repeat({n}, minmax(0, 1fr)) |
.grid-rows-{n} |
grid-template-rows: repeat({n}, minmax(0, 1fr)) |
Columns run 1โ12 ($columns), rows 1โ6 ($rows). Rows stop at 6 on purpose: grid-template-rows only does visible work on a container with a definite height, and templates that deep are rare. Raise $rows if you need more.
The minmax(0, 1fr) โ rather than plain 1fr โ is what stops a long word or a wide <pre> from blowing a track past its share.
Pair with the .gap-* utilities for gutters.
<div class="d-grid grid-cols-1 grid-cols-md-3 gap-16">
<div class="bg-gray-200 p-16">Cell A</div>
<div class="bg-gray-200 p-16">Cell B</div>
<div class="bg-gray-200 p-16">Cell C</div>
</div>Rows need a height to divide, so give the container one:
<div class="d-grid grid-rows-3 gap-8 h-100vh">
<header>Fixed third</header>
<main>Fixed third</main>
<footer>Fixed third</footer>
</div>
Item spans
| Class | CSS |
|---|---|
.grid-column-span-{n} |
grid-column: span {n} / span {n} |
.grid-column-span-full |
grid-column: 1 / -1 |
.grid-row-span-{n} |
grid-row: span {n} / span {n} |
.grid-row-span-full |
grid-row: 1 / -1 |
{n} matches the track ranges โ 1โ12 for columns, 1โ6 for rows. -full spans the first line to the last regardless of how many tracks the container has, which is the one that survives a change to .grid-cols-*.
<div class="d-grid grid-cols-3 gap-16">
<div class="grid-column-span-full bg-gray-200 p-16">Full-width heading</div>
<div class="grid-column-span-2 bg-gray-200 p-16">Two thirds</div>
<div class="bg-gray-200 p-16">One third</div>
</div>Auto-flow โ .grid-flow-*
Controls where items land when they have no explicit placement.
| Class | CSS |
|---|---|
.grid-flow-row |
grid-auto-flow: row |
.grid-flow-column |
grid-auto-flow: column |
.grid-flow-dense |
grid-auto-flow: dense |
.grid-flow-row-dense |
grid-auto-flow: row dense |
.grid-flow-column-dense |
grid-auto-flow: column dense |
row is the CSS default โ the class exists to undo a column set at a narrower breakpoint. dense backfills holes left by spanning items instead of leaving gaps, at the cost of items appearing out of source order (which is also what it does to keyboard and screen-reader order, so use it for galleries, not for content that has to be read in sequence).
.grid-flow-dense on its own is row dense. The two combined forms exist because grid-auto-flow is one property โ .grid-flow-column.grid-flow-dense cannot work, the second class just wins.
<!-- Masonry-ish gallery: no gaps, source order not guaranteed -->
<div class="d-grid grid-cols-4 gap-8 grid-flow-row-dense">
<img class="grid-column-span-2" src="wide.jpg" alt="">
<img src="a.jpg" alt="">
<img src="b.jpg" alt="">
</div>
Alignment
place-items and place-content set both axes at once โ the row axis (align-*) and the column axis (justify-*) โ so .place-center is a one-class replacement for .align-center.justify-center.
Prefix: place Property: place-items
| Class | CSS |
|---|---|
.place-normal |
place-items: normal |
.place-center |
place-items: center |
.place-start |
place-items: start |
.place-end |
place-items: end |
.place-stretch |
place-items: stretch |
Prefix: place-content Property: place-content
| Class | CSS |
|---|---|
.place-content-normal |
place-content: normal |
.place-content-center |
place-content: center |
.place-content-start |
place-content: start |
.place-content-end |
place-content: end |
.place-content-stretch |
place-content: stretch |
.place-content-space-between |
place-content: space-between |
.place-content-space-around |
place-content: space-around |
place-items aligns each item inside its own track; place-content aligns the track grid as a whole inside the container. Both prefixes generate responsive variants (.place-md-center, .place-content-lg-start).
<div class="d-grid grid-cols-3 gap-16 place-center">
<div class="bg-gray-200 p-16">Centered in its cell</div>
<div class="bg-gray-200 p-16">Centered in its cell</div>
<div class="bg-gray-200 p-16">Centered in its cell</div>
</div>