---
title: "Space between siblings set by the parent"
description: "Use it wherever elements sit one above another, such as form fields, the parts of a card or the blocks of an article."
canonical: https://good-css.com/space-between-siblings-set-by-the-parent.md
last-updated: 2026-11-05
---

# Space between siblings set by the parent

Use it wherever elements sit one above another, such as form fields, the parts of a card or the blocks of an article. The parent sets one space between its children, and no child carries a block margin of its own.

```css
.fields {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.prose > * { margin-block: 0; }
.prose > * + * { margin-block-start: var(--flow-space, 1em); }

.prose > :is(h2, h3) { --flow-space: 2em; }
.prose > :is(h2, h3) + * { --flow-space: 0.5em; }
```

Why it works:

- A margin describes the relation between two neighbors, so the element itself is the wrong place for it. A paragraph with `margin-block-end` leaves that margin behind when it is the last child of a padded box.
- `gap` puts space between flex items only. Nothing is left above the first child or below the last.
- `* + *` matches every child that has a sibling before it, so the first child gets no margin. Heydon Pickering named the selector the lobotomized owl.
- The fallback in `var(--flow-space, 1em)` is in `em`, so the space above each element follows that element's font size.
- A custom property on a child changes the space above that child alone. A heading asks for more room above itself, and whatever follows a heading asks for less.

Rules:

- Use the flex form in a component whose children you know. Use the margin form for content you do not control, such as CMS or Markdown output, because flex turns every child into a flex item.
- A flex column stretches its children, so a button or link that is a direct child becomes full width. Set `align-self: start` on it.
- In the margin form, zero the children's block margins first. Without that line the browser's default margins stay above the first child and below the last.
- Keep the `>`. Without it the rule reaches every nested element, list items included.
- The margin form counts a hidden child, so a hidden first child leaves a space at the top. `gap` ignores hidden children.

Support: `gap` in flex layout in Chrome 84, Firefox 63, Safari 14.1. `:is()` in Chrome 88, Firefox 78, Safari 14.

- Borrowed from: Heydon Pickering and Andy Bell, [The Stack](https://every-layout.dev/layouts/stack/), Every Layout · Heydon Pickering, [Axiomatic CSS and Lobotomized Owls](https://alistapart.com/article/axiomatic-css-and-lobotomized-owls/), 2014-10-21 · Andy Bell, [My favourite 3 lines of CSS](https://piccalil.li/blog/my-favourite-3-lines-of-css/), 2023-02-06. Both authors keep the margin form everywhere. This version uses `gap` in components.
- Docs: [MDN: gap](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/gap) · [MDN: next-sibling combinator](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/Next-sibling_combinator)
