As this answer link
As W3 Collapsing Margins :
Adjacent margins of two or more boxes (which may or may not be siblings) can combine to form a single margin. It refers to this type of margins that combine in this way like "collapse" and the resulting combined margin is called "margin of collapse".
This is also explained link :
For example, elements with float, absolute and elements with inline-block, table-cell, and table-captions are not actually block boxes, and block boxes with overflow other than overflow: visibile
generate a new block for formatting the content .
In the context of a content format block, the "boxes" are placed vertically out one after the other, starting from the top of the contents of a block. The vertical distance between the boxes is determined by the margin
property, the vertical margins between the level of the blocks are adjacent in the context of the context causing the collapse.
When collapse does not occur (merging of margins):
- Horizontal margins.
- Overflow elements that are different from visible, such as hidden and auto
- Elements with
float: left;
or float: right;
- Elements with
position
other than static
Note: I still want to improve the answer, because my English is a bit weak and sometimes I get lost in the direction of the sentence, other than the links quoted are outdate, p>
How to avoid collapse
In order for the margin to not affect the parent element you can apply a padding-top
(if you use margin-top
on the child element) and padding-bottom
(if you use margin-bottom
on the child element) on the parent element so it is fixed automatically:
.pai1 {
background: #f00;
color: #fff;
}
.pai2 {
padding: 1px 0; /* adiciona um px no topo e em baixo */
margin: -1px 0; /* ajusta negativamente para que o padding aparente sumir */
background: #00f;
color: #fff;
}
.pai1 .filho, .pai2 .filho {
margin: 20px 0;
}
<p>Teste</p>
<!-- com o problema -->
<div class="pai1">
<div class="filho">teste</div>
</div>
<hr>
<!-- sem o problema -->
<div class="pai2">
<div class="filho">teste</div>
</div>
Using the pseudo element :before
and :after
:
.pai {
background: #f00;
color: #fff;
}
.pai:before, .pai:after {
content: " ";
height: 0;
display: block;
overflow: hidden;
}
.pai .filho {
margin: 20px 0;
}
<p>Teste</p>
<div class="pai">
<div class="filho">teste</div>
</div>
Using overflow: hidden;
(this may not have fixed height), this is perhaps the simplest way to resolve:
.pai {
background: #f00;
color: #fff;
overflow: hidden;
}
.pai .filho {
margin: 20px 0;
}
<p>Teste</p>
<div class="pai">
<div class="filho">teste</div>
</div>