What is margin collapsing, when does it happen, and how do you prevent it?
Advertisement
🧩 Scenario
Architecture Walkthrough
The Three Cases
Margin collapsing means two or more margins in the block direction combine into a single margin instead of adding. It happens in exactly three situations, all confined to block-level boxes in normal flow.
Adjacent siblings. The bottom margin of one block and the top margin of the next block collapse into one. Two paragraphs with margin-bottom: 20px and margin-top: 30px sit 30px apart, not 50px.
Parent and first or last child. If nothing separates a parent's top edge from its first child's top margin, the two collapse and the margin appears outside the parent. The same applies at the bottom with the last child. "Nothing separates them" means the parent has no top border, no top padding, no inline content before the child, and no block formatting context of its own.
Empty blocks. A block with no content, no padding, no border, and no height collapses its own top and bottom margins into a single margin. margin: 20px 0 on an empty div produces 20px of total space, not 40px.
The Resulting Value Is Not Always the Larger One
The common shorthand is "the larger margin wins," which is only true when both are positive. The real rule handles negatives too.
If both margins are positive, the result is the larger. If both are negative, the result is the more negative one, meaning the larger absolute value. If one is positive and one is negative, they are summed. So margin-bottom: 30px next to margin-top: -10px yields a 20px gap, and -20px next to -5px yields -20px.
Why Parent-Child Collapsing Feels Like a Bug
The sibling case is intuitive enough that most developers absorb it without ever naming it. The parent-child case is the one that generates support tickets, because the symptom points at the wrong element.
Consider a card with a background colour and a heading inside it carrying margin-top: 32px. If the card has no top padding or border, that 32px collapses out through the card's top edge. The visible result is the entire card pushed 32px down the page, with the heading flush against the card's top edge and the background not extending into the space at all. Nothing about the card's own CSS explains what you see; the space is coming from its child.
Preventing It
Anything that separates the parent's edge from the child's margin blocks the collapse, and anything that establishes a new block formatting context blocks it as well.
Adding padding-top or border-top to the parent, even a fraction of a pixel, is the cheapest fix and usually the one the design actually wanted. Establishing a block formatting context works too: overflow: hidden or overflow: auto, display: flow-root, display: flex, display: grid, absolute or fixed positioning, and floating all do it. display: flow-root is the purpose-built keyword for this: it creates the formatting context and nothing else, with no clipping and no layout change.
The historically popular overflow: hidden fix is the one to be careful with, because it clips anything that overflows the parent. Box shadows, focus rings, tooltips, and dropdown menus that need to escape the container all get cut off, and the connection between "I fixed a margin problem" and "my dropdown is now truncated" is not obvious weeks later.
Finally, the structural fix: flex and grid items never collapse margins, with each other or with their container. Absolutely and fixed positioned boxes do not collapse either. In practice, laying out a stack with display: flex; flex-direction: column; gap: 24px sidesteps the entire topic, which is why margin collapsing shows up far less in modern codebases than it did in float-based ones.
Key Code Explained
/* Case 1: adjacent siblings -> gap is 30px, not 50px */
.para-a {
margin-bottom: 20px;
}
.para-b {
margin-top: 30px;
}
/* Mixed signs are SUMMED, not "larger wins" -> gap is 20px */
.mixed-a {
margin-bottom: 30px;
}
.mixed-b {
margin-top: -10px;
}
/* Case 2: parent-child. The child margin escapes the parent. */
.card {
background: #fff;
/* no padding-top, no border-top, no formatting context */
}
.card > h2 {
margin-top: 32px; /* pushes the whole .card down, not the h2 inside it */
}
/* Fix A: separate the edges (usually what the design wanted anyway) */
.card-padded {
background: #fff;
padding-top: 1px; /* or any real padding / border-top */
}
/* Fix B: new block formatting context, no side effects */
.card-bfc {
background: #fff;
display: flow-root; /* purpose-built: contains margins, clips nothing */
}
/* Fix C: overflow — works, but CLIPS shadows, tooltips, dropdowns */
.card-overflow {
background: #fff;
overflow: hidden;
}
/* Case 3: empty block collapses its own margins -> 20px total, not 40px */
.spacer {
margin: 20px 0;
/* no content, no height, no padding, no border */
}
/* Structural fix: flex and grid items never collapse */
.stack {
display: flex;
flex-direction: column;
gap: 24px; /* predictable, never collapses, no last-child override */
}
The .card and .card > h2 pair is the example to be able to reproduce on demand. It is the clearest demonstration that collapsing makes the symptom appear on a different element from the cause: the heading's margin visibly moves the card, and reading the card's own rules gives you no hint why.
The contrast between display: flow-root and overflow: hidden is the other detail worth carrying into an interview. Both fix the collapse by establishing a block formatting context, but only one of them also silently clips your box shadows.
Tradeoffs
| Prevention technique | Blocks collapsing | Side effects |
|---|---|---|
padding-top / border-top on parent | Yes, top edge only | Changes visual spacing, adds a visible border |
display: flow-root | Yes, both edges | None; purpose-built for this |
overflow: hidden / auto | Yes, both edges | Clips shadows, tooltips, dropdowns; auto may add scrollbars |
display: flex / grid | Yes, and between children too | Changes the layout model entirely |
| Absolute / fixed positioning | Yes | Removes the box from normal flow |
Use gap instead of margins | N/A, nothing to collapse | Requires a flex or grid parent |
What Interviewers Actually Check
- Whether you can name all three collapsing cases rather than only the sibling one
- Whether you know the resulting value rule for negative and mixed-sign margins, not just "larger wins"
- Whether you can diagnose the parent-child case from the symptom, where the wrong element appears to move
- Whether you know more than one prevention technique and can state the cost of each
- Whether you know flex and grid items are immune, and can explain why that makes the problem rarer today
Follow-Up Questions
- What exactly is a block formatting context, and why does creating one stop margins from collapsing through a parent?
- Why did the CSS working group specify collapsing at all, and what would document flow look like without it?
- What does the
margin-trimproperty propose, and how would it change the:last-child { margin-bottom: 0 }pattern? - Do margins collapse through an element that has
height: 0but a1pxborder? Why or why not? - In a vertical writing mode, which margins collapse, and does the answer change from horizontal writing modes?
Common Candidate Mistakes
- Adding two adjacent margins together, then treating the smaller-than-expected gap as a browser bug rather than specified collapsing behaviour
- Debugging a card that is offset down the page by inspecting the card's own rules, when the offset comes from the first child's
margin-topescaping through the top edge - Reaching for
overflow: hiddenas the reflexive fix and later discovering clipped box shadows, focus rings, or a dropdown that cannot escape the container, whendisplay: flow-rootwould have done the job cleanly - Assuming horizontal margins collapse as well, when only block-direction margins ever do
- Assuming flex or grid items collapse with each other or with their container, when neither ever happens and
gapis the intended spacing tool there
Interview Readiness Checklist
Before you leave this question, make sure you can answer:
- Can you name all three collapsing cases and give a concrete example of each?
- Can you compute the collapsed result when one margin is negative and when both are?
- Can you explain the parent-child case and why the symptom appears on the parent rather than the child?
- Can you list at least four ways to prevent collapsing and state the cost of each?
- Can you explain why flex and grid layouts avoid the problem entirely?
Summary
Margin collapsing combines block-direction margins into a single margin instead of adding them, and it happens in three situations: between adjacent siblings, between a parent and its first or last child when nothing separates their edges, and within an empty block that collapses its own top and bottom margins. Horizontal margins never collapse.
The resulting value is the larger margin only when both are positive. If both are negative, the more negative one wins; if the signs are mixed, the two are summed. So a 30px bottom margin adjacent to a -10px top margin yields a 20px gap.
Prevention comes down to separating the edges or establishing a block formatting context. Adding top padding or a top border to the parent is the cheapest fix. display: flow-root is the purpose-built one, creating the formatting context with no clipping and no layout change, which makes it strictly better than the traditional overflow: hidden trick that silently clips shadows and dropdowns. Structurally, flex and grid items never collapse margins at all, so a column flex container with gap avoids the entire class of problem, which is why the behaviour surfaces far less often in modern layouts than it did in float-based ones.
Do horizontal margins ever collapse?
No. Only margins in the block direction collapse, which is vertical in a standard horizontal writing mode. Left and right margins always add.
Does flexbox collapse margins?
No. Flex and grid items never collapse margins with each other or with their container, which is one reason modern layouts hit this problem far less often.
Advertisement
Stay Updated
Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.
Advertisement