That's the phenomenon know as "collapsing margins" (google it): margins of parent and child are merged, only the larger one of them is applied to the parent.
If necessary, you can avoid that by adding a tiny padding
to the parent (1px):
body {
background: #ddd;
}
.parent {
box-sizing: border-box;
padding: 1px;
background: #fff;
}
.child {
height: 100px;
margin: 20px;
background: red;
}
.a1 {
background: green;
}
<div class="parent">
<div class="child"></div>
<div class="child a1"></div>
</div>
Addition:
The same applies to the body
element, which has a default margin (5px in most browsers), which is the grey area you see in my previous snippet. To avoid that, reset the margin
for html
and body
.
And as @TEmani Afif mentioned in the comments, margin collapsing also applies between sibling elements. So in the following snippet (where I reset the body margin), you see 20px margin not only around both elements, but the margin between the two elements isn't 2 x 20px (as one could believe), but due to collapsing margins only 1 x 20px;
html,
body {
margin: 0;
}
body {
background: #ddd;
}
.parent {
box-sizing: border-box;
background: #fff;
}
.child {
height: 100px;
margin: 20px;
background: red;
}
.a1 {
background: green;
}
<div class="parent">
<div class="child"></div>
<div class="child a1"></div>
</div>