摘要:我們可以注意定義中的幾個關鍵字毗鄰兩個或多個垂直方向和普通流。如何避免外邊距疊加上面講了外邊距的疊加,那如何避免呢,其實只要破壞上面講到的四個條件中的任何一個即可毗鄰兩個或多個普通流和垂直方向。
外邊距疊加一直是前端開發必須了解的一個概念,面試一般也會問到這個問題。所以整理一下相關外邊距疊加相關的知識點。外邊距疊加是什么?什么時候會發生外邊距疊加?如何避免外邊距疊加?
什么是外邊距疊加先來看看 W3C 對于外邊距疊加的定義:
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中,兩個或多個毗鄰的普通流中的盒子(可能是父子元素,也可能是兄弟元素)在垂直方向上的外邊距會發生疊加,這種形成的外邊距稱之為外邊距疊加。
我們可以注意定義中的幾個關鍵字:毗鄰、兩個或多個、垂直方向和普通流。
毗鄰毗鄰說明了他們的位置關系,沒有被 padding、border、clear 和 line box 分隔開。
兩個或多個兩個或多個盒子是指元素之間的相互影響,單個元素不會存在外邊距疊加的情況。
垂直方向Horizontal margins never collapse.
只有垂直方向的外邊距會發生外邊距疊加。水平方向的外邊距不存在疊加的情況。
普通流(in flow)啥為普通流?W3C 只對 out of 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.
從定義中我們可以知道只要不是 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
從定義中我們可以很清楚的知道要符合哪些情況才會發生外邊距折疊:
都屬于普通流的塊級盒子且參與到相同的塊級格式上下文中
沒有被padding、border、clear和line box分隔開
都屬于垂直毗鄰盒子邊緣:
盒子的top margin和它第一個普通流子元素的top margin
盒子的bottom margin和它下一個普通流兄弟的top margin
盒子的bottom margin和它父元素的bottom margin
盒子的top margin和bottom margin,且沒有創建一個新的塊級格式上下文,且有被計算為0的min-height,被計算為0或auto的height,且沒有普通流子元素
Demo 1.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; }
這個 demo 里的 .parent2 和第一個 .child 的 top margin 疊加,導致 .parent1 和 .parent2 之間的邊距為 40px。
Demo 2還是用上面的代碼,.parent2 中的 .child 中的 top margin 和 bottom margin 發生外邊距疊加,它們之間的外邊距為 40px。
Demo 3還是上面的代碼,.parent2 中的最后一個 .child 發生 bottom margin 疊加,.parent2
和 .parent3 之間的邊距為 30px。
.demo { height: 30px; background: red; } .margin-test { margin: 20px 0 30px; }
這個 demo 是上面的第四種情況,元素自身的外邊距 top 和 bottom 發生折疊,我們可以看出 .container 的高度為 90px,這里可以看到 margin-test 的 top 和 bottom 外邊距發生了折疊。
如何避免外邊距疊加上面講了外邊距的疊加,那如何避免呢,其實只要破壞上面講到的四個條件中的任何一個即可:毗鄰、兩個或多個、普通流和垂直方向。
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
普通流中的塊級元素(沒有 border-top、沒有 padding-top)的 margin-top 和它的第一個普通流中的子元素(沒有clear)發生 margin-top 疊加
普通流中的塊級元素(height為 auto、min-height為0、沒有 border-bottom、沒有 padding-bottom)和它的最后一個普通流中的子元素(沒有自身發生margin疊加或clear)發生 margin-bottom疊加
如果一個元素的 min-height 為0、沒有 border、沒有padding、高度為0或者auto、不包含子元素,那么它自身的外邊距會發生疊加
本文首發于有贊技術博客:http://tech.youzan.com/css-ma...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/112313.html
摘要:發生外邊距折疊的條件是什么垂直方向上相鄰的兩個元素這種情況很好理解,就是上面的例子中給出的情況。外邊距折疊后的大小兩個相同大小的正數取某個外邊距的值。即與發生折疊,折疊后的值為。根據塊級格式化上下文來阻止外邊距折疊。 什么是外邊距折疊 準確來說,外邊距折疊應該叫垂直外邊距折疊,因為只會發生在垂直方向上,而水平方向上不會發生。 對于以下簡單的html代碼和css代碼, 請問top塊和bo...
摘要:兩個相鄰的外邊距都是負數時,折疊結果是兩者絕對值的較大值。兩個外邊距一正一負時,折疊結果是兩者的相加的和。 在CSS當中,相鄰的兩個盒子(可能是兄弟關系也可能是祖先關系)的外邊距可以結合成一個單獨的外邊距。這種合并外邊距的方式被稱為折疊,并且因而所結合成的外邊距稱為折疊外邊距。 1. 折疊的結果 兩個相鄰的外邊距都是正數時,折疊結果是它們兩者之間較大的值。 兩個相鄰的外邊距都是負數時...
摘要:它是頁面中的一塊渲染區域,并且有一套渲染規則,它決定了其子元素將如何定位,以及和其他元素的關系和相互作用。而,塊級格式化上下文,就是一個塊級元素的渲染顯示規則。定位和清除浮動的樣式規則只適用于處于同一塊格式化上下文內的元素。 什么是BFC(Block Formatting Context) Formatting context(格式化上下文) 是 W3C CSS2.1 規范中的一個概念...
摘要:它是頁面中的一塊渲染區域,并且有一套渲染規則,它決定了其子元素將如何定位,以及和其他元素的關系和相互作用。而,塊級格式化上下文,就是一個塊級元素的渲染顯示規則。定位和清除浮動的樣式規則只適用于處于同一塊格式化上下文內的元素。 什么是BFC(Block Formatting Context) Formatting context(格式化上下文) 是 W3C CSS2.1 規范中的一個概念...
摘要:當兩個及以上外邊距折疊,合并后的外邊距寬度是發生折疊的外邊距中的最大寬度。如果該元素的外邊距同其父元素的上外邊距折疊,則該盒的上邊框邊緣同其父元盒的上邊框邊緣相同。 2017-07-20: 關于外邊距折疊, 推薦問題: https://segmentfault.com/q/10... 8 盒模型 Box Model URL: http://www.w3.org/TR/CSS2/box...
閱讀 1081·2021-11-24 10:27
閱讀 3354·2021-11-18 10:02
閱讀 2413·2021-11-16 11:45
閱讀 3174·2021-11-15 18:10
閱讀 843·2021-09-22 15:23
閱讀 1545·2019-08-30 15:53
閱讀 3032·2019-08-30 13:20
閱讀 1678·2019-08-30 12:53