I'm trying to understand how margin collapsing behaves when a Block Formatting Context (BFC) is introduced using overflow: hidden
.
Here is a minimal reproducible example:
.outer {
background: lightblue;
}
.inner {
background: lightgreen;
overflow: hidden; /* Triggers BFC */
margin: 30px;
}
p {
margin-top: 30px;
}
<body>
<div class="outer">
<div class="inner">
<p>Paragraph inside a BFC.</p>
</div>
</div>
</body>
From my understanding, setting overflow: hidden
on .inner
should create a Block Formatting Context, which prevents margin collapsing between .inner
and its parent .outer
.
However, when I inspect the layout in Chrome DevTools, it appears that the top margin of .inner
is still collapsing upward, making it look like .outer
has a top margin — even though it doesn’t.
Question:
Why does margin collapsing still occur here even though .inner
should be a BFC? Is there something I’m missing?
BFC works strictly "inwards", so the ("outer") margin of an element that constitutes BFC will still "bleed" (collapse), unless its parent is also BFC.
BFC will only make margins of inside child elements push the BFC's element's boundary, preventing the regular margin-block collapse.
It is nicely visible in your sample, where the BFC is only the .inner
wrapper: the innermost paragraph's margin makes that .inner
parent stretch. If the .inner
did NOT have the overflow: hidden
in your test, it would shrink and let paragraphs margin bleed/collapse into its own, and outside the .outer
, and effectively shrink everything to:
And similarly, if you add extra overflow: hidden
to the .outer
, and keep it on the .inner
as well, you'll get what you probably initially expected: