The simplest form is display: flex; flex-direction: column with a gap. Every Layout's original technique instead uses the "adjacent sibling" combinator: .stack > * + * { margin-block-start: var(--space) }. * + * only selects elements that have a preceding sibling, so the first child gets no extra space — Heydon Pickering nicknamed it the "owl selector," after the shape it makes on the page.
The important part is exposing the gap as a single custom property, --space. Every stack across a page can set --space differently — 8px inside a small card, 32px between page sections — so you tune the "rhythm" of a whole region with one number instead of computing margins per element.
Since gap is now well supported on both flexbox and grid, the owl-selector trick itself is no longer strictly necessary — but its underlying principle still holds: the parent owns the spacing, and children don't need to know it exists. Put margin directly on a child component instead, and that margin follows the component around when it's reused somewhere else — inside a grid cell, say — where it isn't wanted.
When to use
A near-default for almost anything that stacks vertically one item at a time with uniform spacing — elements inside a card, form fields, body paragraphs.