外边距叠加一直是前端开发必须了解的一个概念,面试通常也会问到这个问题。因此整理一下相关外边距叠加相关的知识点。外边距叠加是什么?何时会发生外边距叠加?如何避免外边距叠加?css
先来看看 W3C 对于外边距叠加的定义:html
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.前端
大概意思是:在CSS中,两个或多个毗邻的普通流中的盒子(多是父子元素,也多是兄弟元素)在垂直方向上的外边距会发生叠加,这种造成的外边距称之为外边距叠加。面试
咱们能够注意定义中的几个关键字:毗邻、两个或多个、垂直方向和普通流。less
毗邻说明了他们的位置关系,没有被 padding
、border
、clear
和 line box
分隔开。this
两个或多个盒子是指元素之间的相互影响,单个元素不会存在外边距叠加的状况。翻译
Horizontal margins never collapse.code
只有垂直方向的外边距会发生外边距叠加。水平方向的外边距不存在叠加的状况。orm
啥为普通流?W3C 只对 out of flow 做了定义:htm
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.
从定义中咱们能够知道只要不是 float
、absolutely positioned
和 root element
时就是 in 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
从定义中咱们能够很清楚的知道要符合哪些状况才会发生外边距折叠:
都属于垂直毗邻盒子边缘:
.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>
这个 demo 里的 .parent2
和第一个 .child
的 top margin 叠加,致使 .parent1
和 .parent2
之间的边距为 40px。
仍是用上面的代码,.parent2
中的 .child
中的 top margin 和 bottom margin 发生外边距叠加,它们之间的外边距为 40px。
仍是上面的代码,.parent2
中的最后一个 .child
发生 bottom margin 叠加,.parent2
和 .parent3
之间的边距为 30px。
.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>
这个 demo 是上面的第四种状况,元素自身的外边距 top
和 bottom
发生折叠,咱们能够看出 .container
的高度为 90px,这里能够看到 margin-test
的 top
和 bottom
外边距发生了折叠。
上面讲了外边距的叠加,那如何避免呢,其实只要破坏上面讲到的四个条件中的任何一个便可:毗邻、两个或多个、普通流和垂直方向。
W3C也对此作了总结:
翻译一下:
本文首发于有赞技术博客:http://tech.youzan.com/css-ma...