外邊距疊加一直是前端開發必須瞭解的一個概念,面試通常也會問到這個問題。因此整理一下相關外邊距疊加相關的知識點。外邊距疊加是什麼?何時會發生外邊距疊加?如何避免外邊距疊加?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...