.stack {
display: flex;
flex-direction: column;
justify-content: flex-start;
gap: var(--flow-space, 1em);
}
<div class="stack">
<div><!-- child --></div>
<div><!-- child --></div>
<div><!-- etc --></div>
</div>
layout
Flow elements require white space to physically and conceptually seperate them
from the elements coming before and after them. This is the main purpose of the
margin
property.
However, design systems concieve elements and components in isolation. At the time of conception, it is not settled whether there will be surrounding content or what the nature of that content will be. One element or component is likely to appead in different contexts, and the requirement for spacing will differ.
We are in the habbit of styling elements, or classes of elements, directly: we
make style declarations belong to elements. Typically, this does not produce
any issues, but margin
is really a property of the relationship between two
proximate elements. The following code is therefore problematic:
p {
margin-bottom: 1.5rem;
}
Since the declaration is not context sensitive, any correct application of the
margin is a matter of luck. If the paragraph is proceeded by another element,
the effect is desireable. But a :last-child
paragraph produces a redundant
margin. Inside a padded parent element, this redundant margin combines with the
parent's padding to produce double the intended space. This is just one problem
with this approach.
The trick it to style the context, not the individual element(s):
.stack {
display: flex;
flex-direction: column;
justify-content: flex-start;
gap: var(--flow-space, 1em);
}
flow-space
If --flow-space
is defined, it uses that, or defaults to 1em
, which is relative
to the elements font size.
This is the magic, when you're using a type scale, 1em has a lot of value. It means we get some nice rhythm, just by dropping in our CSS. We can inscrease the space on top of headings and block qoutes like this:
:is(h1, h2, h3, blockquote) {
--flow-space: 1.5em;
}
:is(h1, h2, h3) + * {
--flow-space: 0.5em;
}