標籤:

外邊距摺疊-磨人的小妖精

外邊距摺疊(塌陷)這個問題,我在寫頁面的時候不知道遇到多少次了,以前都是對這個小妖精無可奈何,後來仔仔細細研究了一遍之後發現也沒什麼。(好像這個技術博客的畫風有點奇特

好了,言歸正題,外邊距摺疊的定義就是

外邊距摺疊就是塊的頂部外邊距和底部外邊距有時被組合(摺疊)為單個外邊距,其大小是組合到其中的最大外邊距,這種行為稱為外邊距塌陷(margin collapsing)

外邊距摺疊產生的情況

產生外邊距摺疊的情況一般分為以下三種:

1. 塊級父元素與其第一個/最後一個子元素

h1 {n margin: 0;n background: #cff;n}n#div1{ntmargin: 40px 0 25px 0;n tbackground: #999;n}n#div2{ntmargin: 20px 0 10px 0;ntbackground: #cff;n}n<h1>這是一個標題</h1>n<div id="div1">nt<div id="div2" >這是第一個塊級盒子</div>n</div>n

測試的結果是:h1與div2之間的margin值是40px而不是想像中的60px。

為什麼會出現這種個情況呢?這也正是小妖精對於初學者來說一直纏著我們的地方。

根據MDN,產生的原因就在於

如果塊級父元素中,不存在上邊框、上內補、inline content、 清除浮動這四條屬性(對於上邊框和上內補,也可以說,當上邊距及上內補寬度為0時),那麼這個塊級元素和其第一個子元素的上邊距就會發生摺疊。這個摺疊之後的值在這裡取的就是兩者之間的最大值。

對於塊級元素與最後一個子元素的下邊界發生的摺疊也是同理的

那摺疊出來的值只有取最大嘛?別急,還有另外一些規則會在下面說慢慢說。

2. 相鄰的兄弟塊級元素

div {ntwidth:100px;ntheight:100px;ntmargin:40px;n}n<div id="div1" >這是第一個塊級盒子</div>n<div id="div2" >這是第二個塊級盒子</div>n

測試的結果是兩個div之間的邊距是40px而不是80px,其實道理也就和剛剛一樣啦

3. 空塊元素

#div1,#div2 {ntmargin:0px;n}n#voidDiv {ntmargin-top:40px;ntmargin-bottom:40px;n}n<div id="div1" >這是第一個塊級盒子</div>n<div id="voidDiv"></div>n<div id="div2" >這是第二個塊級盒子</div>n

測試的結果是div1與div2之間的邊距是40px而不是80px。

根據MDN,產生的原因就在於

如果存在一個空的塊級元素,其 border、padding、inline content、height、min-height都不存在,那麼此時上下邊距就會發生摺疊

外邊距摺疊的計算

外邊距摺疊的計算一般是以下三種方法

  • 如果兩個外邊距都為正數,那麼取其中較大的數
  • 如果一個為正數一個為負數,那麼取它們的代數和
  • 如果兩個都為負數,那麼取它們其中絕對值大的數

如何解決外邊距摺疊

1. 對於父子級塊狀元素

既然知道了外邊距摺疊產生的條件,那麼解決這個小妖精的方法也就隨之出來啦!

對於父子級塊狀元素解決外邊距摺疊的方法一般分為三大類

  • 給父級塊級元素設置border-top,我一般是設置為:border-top:1px solid transparent
  • 給父級塊級元素設置一個padding-top,這個值就根據自己的布局來定吧。
  • 最後一種方法,是給父級塊級元素觸發一個BFC(Block formatting contexts-塊級格式上下文)

那問題又來了,BFC又是什麼呢?

初識BFC

w3c規範中的BFC定義:

浮動元素和絕對定位元素,非塊級盒子的塊級容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不為「visiable」的塊級盒子,都會為他們的內容創建新的BFC(塊級格式上下文)。

在BFC中,盒子從頂端開始垂直地一個接一個地排列,兩個盒子之間的垂直的間隙是由他們的margin 值所決定的。在一個BFC中,兩個相鄰的塊級盒子的垂直外邊距會產生摺疊。

其實簡單點說BFC就是一個不受外部布局影響的一個箱子而已,在這裡我們不細談BFC,具體可以Google或者等我更下一次BFC(嘻嘻嘻)。

具體怎麼觸發BFC呢?一般觸發BFC的條件包括:

  • 浮動元素:float除了none之外
  • 用position絕對定位的元素,以及fixed固定定位的元素
  • display: inline-block等
  • overflow:除了visiable

2. 對於兄弟級塊狀元素

對於兄弟級塊狀元素,解決的方法一般有兩種:

  • 直接只寫一邊的margin例如都是margin-top或者都是margin-bottom,我覺得這是我用過最簡單的方法了,直接就避免了塌陷。
  • 給兩個塊狀元素形成兩個不同的BFC,觸發的方法我一般用的是 overflow: hidden;

3. 對於空塊狀元素

對於空的塊狀元素,解決的方法就很多啦,列舉以下幾種:

  • 設置border
  • 設置padding
  • 設置inline-block等等方法都可

看到最後,我們大概就能傲嬌地挑起小妖精下巴不再讓她得瑟了,2333333(玩笑而已

如果還有什麼需要交流的問題歡迎吖,寫下來也是想著總結記錄而已啦!也希望這篇文章能幫助一點點你解決一點點困擾啦~(排版總亂orz


推薦閱讀:

Markdown入門指南
「每日一題」為什麼不建議將 font-size 設置為 12px 以下?
【譯】CSS變數的正確使用方法
CSS 新的長度單位 fr 你知道么?
實現CSS居中的多種方法

TAG:CSS |