From Mastering margin collapsing:
Margin collapsing occurs in three basic cases:
[…]
Parent and first/last child: If there is no border, padding, inline part, block formatting context created, […], then those margins collapse.
Then, the Block formatting context article says:
A block formatting context is created by at least one of the following:
[…]
- anonymous table cells implicitly created by the elements with
display: table
, table-row
, table-row-group
, table-header-group
, table-footer-group
(which is the default for HTML tables, table rows, table bodies, table headers and table footers, respectively), or inline-table
So a <table>
creates a block formatting context. This is why the margins don’t collapse. You can change the <table>
s into <div>
s with display: table;
or display: inline-block;
(which also creates a block formatting context); this will prevent margin collapsing, too:
.outer { border: 1px solid orange }
.inner { margin-bottom: 20px }
.inner > div { display: table }
<div class="outer">
<div class="inner"><div></div></div>
<div class="inner"><div></div></div>
<div class="inner"><div></div></div>
<div class="inner"><div></div></div>
</div>