深入理解CSS外邊距摺疊
外邊距疊加一直是前端開發必須了解的一個概念,面試一般也會問到這個問題。所以整理一下相關外邊距疊加相關的知識點。外邊距疊加是什麼?什麼時候會發生外邊距疊加?如何避免外邊距疊加?
什麼是外邊距疊加
先來看看對於外邊距疊加的定義:
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中,兩個或多個毗鄰的普通流中的盒子(可能是父子元素,也可能是兄弟元素)在垂直方向上的外邊距會發生疊加,這種形成的外邊距稱之為外邊距疊加。
我們可以注意定義中的幾個關鍵字: 、 、 和 。
毗鄰
毗鄰說明了他們的位置關係,沒有被 、 、 和 分隔開。
兩個或多個
兩個或多個盒子是指元素之間的相互影響,單個元素不會存在外邊距疊加的情況。
垂直方向
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.
從定義中我們可以知道只要不是 、 和 時就是 。
什麼時候會發生外邊距疊加
外邊距疊加存在兩種情況:一是父子外邊距疊加;二是兄弟外邊距疊加。
對於什麼是毗鄰的外邊距也有定義:
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
從定義中我們可以很清楚的知道要符合哪些情況才會發生外邊距摺疊:
都屬於普通流的塊級盒子且參與到相同的塊級格式上下文中
沒有被 、 、 和 分隔開
都屬於垂直毗鄰盒子邊緣:
盒子的 和它第一個普通流子元素的
盒子的 和它下一個普通流兄弟的
盒子的 和它父元素的
盒子的 和 ,且沒有創建一個新的塊級格式上下文,且有被計算為0的 ,被計算為0或 的 ,且沒有普通流子元
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; }
這個demo里的 和第一個 的 疊加,導致 和 之間的邊距為 。
demo2:
還是用上面的代碼, 中的 中的 和 發生外邊距疊加,它們之間的外邊距為 。
demo3:
還是上面的代碼, 中的最後一個 發生 疊加, 和 之間的邊距為 。
demo4:.demo { height: 30px; background: red; } .margin-test { margin: 20px 0 30px; }
這個demo是上面的第四種情況,元素自身的外邊距 和 發生摺疊,我們可以看出 的高度為 ,這裡可以看到 的 和 外邊距發生了摺疊。
如何避免外邊距疊加
上面講了外邊距的疊加,那如何避免呢,其實只要破壞上面講到的四個條件中的任何一個即可: 、 、 和 。
也對此做了總結:
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、不包含子元素,那麼它自身的外邊距會發生疊


※話說PHP的Memcache&Memcached這兩個擴展之間的關係,你都摸清楚了嗎?
※收納,本是一件簡單的事
※中國網紅的營銷能量
※表情包背後的大生意,Giphy Inc.百萬美元領投表情雲
TAG:推酷 |
※深入理解HTTPS原理、過程
※深入理解磁碟碎片與RAM碎片
※深入理解JVM—JVM內存模型
※深入理解 RPC 之服務註冊與發現篇
※深入淺出理解A3C強化學習
※深入理解 RPC 消息協議設計
※理解MySQL架構
※深入理解GIF文件格式
※JSONP淺顯理解
※如何深入理解EOS是一個雲操作系統
※深入理解 RPC:基於 Python 自建分散式高並發 RPC 服務
※深入理解Git的實現原理
※深入理解Flask
※深入理解 ES Modules
※理解下HTTPS的原理及流程了
※輕鬆理解什麼是 SQL 注入
※深度理解PLC的工作原理
※更深入理解 Python 中的迭代
※深入理解消息中間件技術之RabbitMQ服務
※淺談我對OKR的理解