margin系列之外邊距摺疊
原文地址:margin系列之外邊距摺疊 by @doyoe
不懷疑你也在工作中遇見過
幾乎可以不用懷疑,前端工作中的你一定遇見過 margin
摺疊。
不確定?彆著急,你可能寫過這樣的程式碼:
CSS:
p{
margin: 50px;
}
HTML:
<div id="demo">
<p>我是一個華麗的段落,別看我文字少</p>
<p>我是另一個華麗的段落</p>
</div>
大家覺得這 2p
之間會發生點什麼?是會合體呢?還是分開?來看看 DEMO1
margin摺疊
好吧,它們真的合體了。按照常規思路,這 2p
之間的空白應該是第一個 p
的 margin-bottom
50px 加上第二 p
的 margin-top
50px,即 50 + 50px = 100px
,但結果總是出乎意料不是麼?它們之間只剩下了 50px
,這就是 margin摺疊
。所以任何人遇見過我都不會覺得意外,因為這樣的Code看起來沒有任何問題。
它們之間到底發生了些什麼?
這 2p
內部到底發生了什麼,才會有這樣的表現?
早在CSS1中就有對 margin
摺疊的說明,我們來看看:
原文:The width of the margin on non-floating block-level elements specifies the minimum distance to the edges of surrounding boxes. Two or more adjoining vertical margins (i.e., with no border, padding or content between them) are collapsed to use the maximum of the margin values. In most cases, after collapsing the vertical margins the result is visually more pleasing and closer to what the designer expects.
翻譯:外邊距用來指定非浮動元素與其周圍盒子邊緣的最小距離。兩個或兩個以上的相鄰的垂直外邊距會被摺疊並使用它們之間最大的那個外邊距值。多數情況下,摺疊垂直外邊距可以在視覺上顯得更美觀,也更貼近設計師的預期。
從這段話中,我們能獲得一些有用的資訊:
- 發生摺疊需要是相鄰的非浮動元素;
- 摺疊發生在垂直外邊距上,即margin-top/margin-bottom;
- 摺疊後取其中最大的那個margin值作為最終值;
所以 DEMO1
中的 2p
符合摺疊的條件,相鄰且都不是浮動元素,於是它們就自然合體了。至於取最大的那個值作為摺疊後的最終值,因為都是50px,所以無所謂誰誰誰了。
為什麼會有margin摺疊這樣的設計?
從上文中,應該能知道個大概?在前面的文章中,我們說過,CSS的基本模型是排版。只是前端工程師現在做得更多的是 佈局
而非 文字排版
,但CSS並未界定這兩者的區別。而 margin
摺疊是為實現文字排版的段落間距而提供的特性。所以很多時候 margin
摺疊的特性會帶給我們諸多疑惑。
再回到 DEMO1
仔細看看,你會驚訝的發現,其實你只要設定每個 p
有相同的垂直外邊距,由於發生會 margin
摺疊,所有的 p
之間,及包含塊與 p
之間的間隙都是相同的,非常美妙且實現簡單,不是麼?這正印證了我們引用 CSS1
中的那短話:多數情況下,摺疊垂直外邊距可以在視覺上顯得更美觀,也更貼近設計師的預期。
浮動元素真的不會發生margin摺疊嗎?
質疑精神一直都是進步最重要的驅動力之一,我們為什麼不能呢?改下程式碼看看:
CSS:
p{
float: left;
margin: 50px;
}
只改CSS程式碼,HTML不變。迫不及待的想看到驗證情況,來吧,還等什麼。DEMO2
驗證浮動元素是否會發生margin摺疊。
結果告訴我們,真的沒有摺疊,2p
間的間隙足足有 100px
。
剩下的2點大家就自行驗證吧,相信你能得到滿意的額測試結果。
僅此而已?
回想一下我們在 margin系列之百分比 文中提到過受書寫模式影響的一些特性,非常不幸,margin
摺疊正好是其中之一。
是的,在CSS2及後續的規範中,將margin
摺疊描述得更為詳盡了。
在水平書寫模式下,發生 margin
摺疊的是垂直方向,即 margin-top/margin-bottom
,在垂直書寫模式下,margin
摺疊發生在水平方向上,即 margin-right/margin-left
。
現在我們來解釋一下到底什麼是margin摺疊?
在CSS中,兩個或以上的塊元素(可能是兄弟,也可能不是)之間的相鄰外邊距可以被合併成一個單獨的外邊距。通過此方式合併的外邊距被稱為摺疊,且產生的已合併的外邊距被稱為摺疊外邊距。
處於同一個塊級上下文中的塊元素,沒有行框、沒有間隙、沒有內邊距和邊框隔開它們,這樣的元素垂直邊緣毗鄰,則稱之為相鄰。
什麼是垂直邊緣毗鄰?
- 元素的上外邊距和其屬於常規流中的第一個孩子的上外邊距。
- 元素的下外邊距和其屬於常規流中的下一個兄弟的上外邊距。
- 屬於常規流中的最後一個孩子的下外邊距和其父親的下外邊距,如果其父親的高度計算值為
auto
。 - 元素的上、下外邊距,如果該元素沒有建立新的塊級格式上下文,且
min-height
的計算值為零、height
的計算值為零或auto
、且沒有屬於常規流中的孩子。
說得很清楚了,我想是的。你可能需要注意的是發生 margin
摺疊的元素不一定是兄弟關係,也能是父子或祖先的關係。
如何避免margin摺疊?
我想肯定有人要問,那我不想有 margin
摺疊的情況發生,該怎麼辦?其實從上面的規則中,我們已經可以抽出避免 margin
摺疊的條件來。
margin
摺疊元素只發生在塊元素上;- 浮動元素不與其他元素
margin
摺疊; - 定義了屬性overflow且值不為visible(即建立了新的塊級格式化上下文)的塊元素,不與它的子元素髮生
margin
摺疊; - 絕對定位元素的
margin
不與任何margin
發生摺疊。 - 特殊:根元素的
margin
不與其它任何margin
發生摺疊; - 如果常規流中的一個塊元素沒有
border-top
、padding-top
,且其第一個浮動的塊級子元素沒有間隙,則該元素的上外邊距會與其常規流中的第一個塊級子元素的上外邊距摺疊。 可能有些繞,我們驗證一下DEMO3
,在其第一個浮動子元素加個全形空格做間隙,來個反證DEMO4
- 如果一個元素的
min-height
屬性為0,且沒有上或下邊框以及上或下內邊距,且height
為0或者auto
,且不包含行框,且其屬於常規流的所有孩子的外邊距都摺疊了,則摺疊其外邊距。驗證一下DEMO5
這樣幹掉margin摺疊
如果不想發生 margin
摺疊,那麼你可以根據上面的規則得到方法,不是麼?我把它改成非塊元素,讓它浮動,讓它絕對定位,讓它 overflow:hidden
DEMO6
,用邊框隔開它們 DEMO7
...隨你怎樣,信手拈來。
今天狀態不太好,有些地方寫得欠妥,之後可能會修改一下。
BTW: 這篇文章裡可能有不少之前文章中沒出現過的名詞,比如:塊級上下文、行框、常規流,如果你對此不甚瞭解,可以先找資料看看,我以後會講到。
enjoy it.
可參考:
- http://www.w3.org/TR/css3-box/#margins
- http://www.w3.org/TR/css3-box/#collapsing-margins
- http://dev.w3.org/csswg/css-box/#collapsing-margins
- http://www.w3.org/TR/CSS1/#vertical-formatting
margin系列文章:
相關文章
- CSS margin 外邊距CSS
- CSS margin外邊距CSS
- CSS margin負外邊距CSS
- scss自動生成margin padding邊距CSSpadding
- CSS中上下margin的傳遞和摺疊CSS
- 用padding和margin撐起左右邊距padding
- VsCode顯示左邊摺疊程式碼+-按鈕VSCode
- 面試之CSS篇 - 邊距重疊與BFC面試CSS
- 消費摺疊
- Margin會重疊,你造嗎
- BootStrap | 例項 - 摺疊boot
- java之常量摺疊Java
- 垂直margin為什麼會重疊
- 蘋果OLED摺疊手機和可摺疊平板電腦情景分析蘋果
- 左右邊距可控
- 可摺疊iPhone概念設計圖:手機可摺疊秒變筆記本iPhone筆記
- vivo X Fold系列通過TUV萊茵摺疊無憂認證
- 榮耀摺疊,太卷啦
- 使用Jquery和CSS摺疊影象jQueryCSS
- 引用摺疊和完美轉發
- vscode摺疊展開程式碼VSCode
- CSS 負外邊距CSS
- CSS padding 內邊距CSSpadding
- CSS padding內邊距CSSpadding
- 曝蘋果摺疊屏iPhone再度延期2年!或將研發可摺疊MacBook蘋果iPhoneMac
- 可摺疊,可標記日曆
- Axure 教程:製作摺疊選單
- 摺疊屏手機華為、小米、三星、OPPO都有,誰的摺疊屏最厲害?
- 我們到底需不需要摺疊屏?不買摺疊屏手機的5個理由!
- CSS 盒子的邊距塌陷CSS
- CSS 右內邊距失效CSS
- CSS 右外邊距失效CSS
- CSS 外邊距合併CSS
- 【Unity】(UI)抽屜式摺疊皮膚UnityUI
- 為什麼評論會被摺疊?
- AI巨幕之下,資料不只摺疊AI
- 坐穩國內摺疊機寶座,華為摺疊屏手機貢獻47.4%市場份額
- win10右下角圖示如何摺疊 win10右下角圖示摺疊的方法Win10
- 外邊距與絕對定位