## 什么是外边距叠加

In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.

### 垂直方向

Horizontal margins never collapse.

### 普通流(in flow)

An element is called out of flow if it is floated, absolutely positioned, or is the root element.An element is called in-flow if it is not out-of-flow.

## 什么时候会发生外边距叠加

W3C对于什么是毗邻的外边距也有定义：

Two margins are adjoining if and only if: - both belong to in-flow block-level boxes that participate in the same block formatting context - no line boxes, no clearance, no padding and no border separate them - both belong to vertically-adjacent box edges, i.e. form one of the following pairs:

• top margin of a box and top margin of its first in-flow child
• bottom margin of box and top margin of its next in-flow following sibling
• bottom margin of a last in-flow child and bottom margin of its parent if the parent has "auto" computed height
• top and bottom margins of a box that does not establish a new block formatting context and that has zero computed "min-height", zero or "auto" computed "height", and no in-flow children

• 都属于普通流的块级盒子且参与到相同的块级格式上下文中
• 没有被paddingborderclearline box分隔开
• 都属于垂直毗邻盒子边缘：
• 盒子的top margin和它第一个普通流子元素的top margin
• 盒子的bottom margin和它下一个普通流兄弟的top margin
• 盒子的bottom margin和它父元素的bottom margin
• 盒子的top marginbottom margin，且没有创建一个新的块级格式上下文，且有被计算为0的min-height，被计算为0或autoheight，且没有普通流子元素

demo1：

.parent1 {
height: 20px;
background: yellow;
margin-bottom: 20px;
}
.parent2 {
margin: 20px 0 30px;
}
.parent3 {
height: 20px;
background: green;
margin-top: 20px;
}
.child {
background: red;
height: 20px;
margin: 40px 0 30px;
}

<div class="parent1"></div>
<div class="parent2">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
<div class="parent3"></div>


demo2：

demo3：

demo4：

.demo {
height: 30px;
background: red;
}
.margin-test {
margin: 20px 0 30px;
}

<div class="container">
<div class="demo"></div>
<div class="margin-test"></div>
<div class="demo"></div>
</div>


## 如何避免外边距叠加

W3C也对此做了总结：

• Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
• Margins of elements that establish new block formatting contexts (such as floats and elements with "overflow" other than "visible") do not collapse with their in-flow children.
• Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).
• Margins of inline-block boxes do not collapse (not even with their in-flow children).
• The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.
• The top margin of an in-flow block element collapses with its first in-flow block-level child"s top margin if the element has no top border, no top padding, and the child has no clearance.
• The bottom margin of an in-flow block box with a "height" of "auto" and a "min-height" of zero collapses with its last in-flow block-level child"s bottom margin if the box has no bottom padding and no bottom border and the child"s bottom margin does not collapse with a top margin that has clearance.
• A box"s own margins collapse if the "min-height" property is zero, and it has neither top or bottom borders nor top or bottom padding, and it has a "height" of either 0 or "auto", and it does not contain a line box, and all of its in-flow children"s margins (if any) collapse.

• 浮动元素不会与任何元素发生叠加，也包括它的子元素
• 创建了BFC的元素不会和它的子元素发生外边距叠加
• 绝对定位元素和其他任何元素之间不发生外边距叠加，也包括它的子元素
• inline-block元素和其他任何元素之间不发生外边距叠加，也包括它的子元素
• 普通流中的块级元素的margin-bottom永远和它相邻的下一个块级元素的margin-top叠加，除非相邻的兄弟元素clear