Skip to content

PRIMITIVE

Flow

Vertical rhythm between siblings, so you never write a margin again. A step for tight, one for ordinary, one for loose, and nothing in between.

A section

Head, content, note β€” and not one child carries a margin. The container owns the gap.

01 β€” A SECTION
STEP--ds-flow
BETWEENevery sibling

Nothing here carries a margin. The container owns the gap.

HTML
<div class="flow" style="width:100%">
  <div class="section-head">
    <span class="section-head-kicker">01 β€” A SECTION</span>
    <span class="section-head-rule"></span>
  </div>
  <div class="rule-stack rule-stack-on-sunk">
    <div class="rule-row rule-row-spec"><span class="rule-row-key">STEP</span><span class="rule-row-value">--ds-flow</span></div>
    <div class="rule-row rule-row-spec"><span class="rule-row-key">BETWEEN</span><span class="rule-row-value">every sibling</span></div>
  </div>
  <p class="placeholder-caption">Nothing here carries a margin. The container owns the gap.</p>
</div>

The steps

FLOW-TIGHT Β· 24px
blocks that belong to each other
…
FLOW Β· the default step
a section head to its content
…
FLOW-LOOSE Β· the larger break
two ideas in one section
…
HTML
<div class="flow flow-tight" style="width:100%">
  <span class="section-head-kicker section-head-kicker-quiet">FLOW-TIGHT Β· 24px</span>
  <div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">blocks that belong to each other</span></div>
  <div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">…</span></div>
</div>
<div class="flow" style="width:100%">
  <span class="section-head-kicker section-head-kicker-quiet">FLOW Β· the default step</span>
  <div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">a section head to its content</span></div>
  <div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">…</span></div>
</div>
<div class="flow flow-loose" style="width:100%">
  <span class="section-head-kicker section-head-kicker-quiet">FLOW-LOOSE Β· the larger break</span>
  <div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">two ideas in one section</span></div>
  <div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">…</span></div>
</div>

Reference

Read from primitives/flow.css when this page was built, so it cannot fall behind the stylesheet.

CLASSES.flow.flow-tight.flow-loose
SETTINGSSet the first on one element; a theme sets the second for all of them.--flow β€” falls back to --ds-flow
READS--ds-flow-loose--ds-flow-tight

Notes

WHY THIS EXISTS

Before it did, one page built on this system had grown five spellings of one gap β€” 24, 32, 36, 44 and 56 pixels β€” each a guess made at the moment it was needed. That is what a system without a named rhythm produces, however careful the person writing it.

The steps are measured off the source design rather than invented. It puts 44px after a section head twenty times and 56px before a larger break seventeen more. That is a rhythm, not a mood, and it transfers.

GAP, NOT MARGINS

A margin collapses, needs a :first-child exception, and doubles up where two spaced blocks meet. A gap does none of that β€” and a block moved to the top of a stack stops having a top margin without anybody editing it.

CHANGING THE STEP

Use .flow-tight or .flow-loose. For a one-off, set the variable on the container β€” style="--flow: …" β€” never a margin on a child. That is the only sanctioned override; a consuming site is where it can be enforced, and a check there should refuse the alternative.