Luiz Tanure
css apr 08, 2026 5 min read

Margin collapse, again

Every few years a junior dev rediscovers margin collapse and writes a thread about it. This is mine, except I'm trying to make peace with the rule, not abolish it.

Margin collapse is one of those CSS rules people remember as a gotcha. You set margin-bottom: 32px on a heading and margin-top: 32px on the paragraph below it, expecting 64px between them. You get 32px. The internet calls this a bug.

It’s not a bug

The rule is older than CSS-the-spec. Print typography has worked this way for centuries: when two block-level elements meet vertically, the larger of their two surrounding margins wins. The smaller one is absorbed.

This makes sense if you think of margin not as space I want around me but as the minimum distance I require from my neighbour. Two elements both saying “I want 32px of breathing room” don’t need 64px between them, they need 32px, and they both get what they asked for.

When it breaks

The rule breaks when a parent’s margin starts to collapse with its first child’s margin. You add a wrapper, the wrapper has no padding, and suddenly the child’s margin-top punches a hole through the parent and pushes the parent down.

Three escape hatches, in increasing order of weight:

  1. padding-top: 1px on the parent. Cheap and ugly.
  2. display: flow-root on the parent. The newest, cleanest answer.
  3. A flex or grid container. Margin collapse doesn’t happen inside flex/grid, period.

I default to flow-root now. It’s a one-line opt-out with no layout side-effects.

The thing I keep forgetting

margin-block is the logical-property version. margin-block-start and margin-block-end collapse exactly the same way margin-top and margin-bottom do, but the rule still confuses my brain because the names don’t say “vertical” anymore. RTL languages still get vertical collapse on the block axis. Nothing changes, but the mental model has to update.