CSS margin合併問題

在CSS當中,相鄰的兩個盒子(多是兄弟關係也多是祖先關係)的外邊距能夠結合成一個單獨的外邊距。這種合併外邊距的方式被稱爲摺疊,而且於是所結合成的外邊距稱爲摺疊外邊距。css

1. 摺疊的結果

  1. 兩個相鄰的外邊距都是正數時,摺疊結果是它們二者之間較大的值。
  2. 兩個相鄰的外邊距都是負數時,摺疊結果是二者絕對值的較大值。
  3. 兩個外邊距一正一負時,摺疊結果是二者的相加的和。

2. 條件

產生摺疊的必備條件:margin必須是鄰接的
而根據w3c規範,兩個margin是鄰接的必須知足如下條件:html

  1. 必須是處於常規文檔流(非float和絕對定位)的塊級盒子,而且處於同一個BFC當中。
  2. 沒有線盒,沒有空隙(clearance,下面會講到),沒有padding和border將他們分隔開
  3. 都屬於垂直方向上相鄰的外邊距,能夠是下面任意一種狀況前端

    • 元素的margin-top與其第一個常規文檔流的子元素的margin-top
    • 元素的margin-bottom與其下一個常規文檔流的兄弟元素的margin-top
    • height爲auto的元素的margin-bottom與其最後一個常規文檔流的子元素的margin-bottom
    • 高度爲0而且最小高度也爲0,不包含常規文檔流的子元素,而且自身沒有創建新的BFC的元素的margin-top和margin-bottom

2.1 條件解讀

  1. 建立了新的BFC的元素(例如浮動元素或者'overflow'值爲'visible'之外的元素)與它的子元素的外邊距不會摺疊
  2. 浮動元素不與任何元素的外邊距產生摺疊(包括其父元素和子元素)
  3. 絕對定位元素不與任何元素的外邊距產生摺疊
  4. inline-block元素不與任何元素的外邊距產生摺疊
  5. 一個常規文檔流元素的margin-bottom與它下一個常規文檔流的兄弟元素的margin-top會產生摺疊,除非它們之間存在間隙(clearance)。
  6. 一個常規文檔流元素的margin-top 與其第一個常規文檔流的子元素的margin-top產生摺疊,條件爲父元素不包含 padding 和 border ,子元素不包含 clearance。
  7. 一個 'height:auto' 而且 'min-height:0'的常規文檔流元素的 margin-bottom 會與其最後一個常規文檔流子元素的 margin-bottom 摺疊,條件爲父元素不包含 padding 和 border ,子元素的 margin-bottom 不與包含 clearance 的 margin-top 摺疊。
  8. 一個不包含border-top、border-bottom、padding-top、padding-bottom的常規文檔流元素,而且其 'height' 爲 0 或 'auto', 'min-height:0',其裏面也不包含行盒(line box),其自身的 margin-top 和 margin-bottom 會摺疊。

注意:
浮動元素和絕對定位元素不與其餘盒子產生外邊距摺疊是由於元素會脫離當前的文檔流,違反了上面所述的兩個margin是鄰接的條件同時,又由於浮動和絕對定位會使元素爲它的內容建立新的BFC,所以該元素和子元素所處的BFC是不相同的,所以也不會產生margin的摺疊。segmentfault

可是浮動元素脫離了當前的BFC並不影響它後面的兄弟元素,後面的兄弟元素與浮動元素前面的元素依然在同一個BFC當中,因此,它們之間的margin仍是會摺疊的。瀏覽器

2.2 空隙 clearance

當浮動元素以後的元素設置clear以閉合相關方向的浮動時,根據w3c規範規定,閉合浮動的元素會在其margin-top以上產生必定的空隙(clearance),該空隙會阻止元素margin-top的摺疊,並做爲間距存在於元素的margin-top的上方。關於這個間距的計算稍微有點複雜,但實際工做中你並不須要去計算它。微信

3. 如何解決

使用BFC解決margin合併問題能夠參考這篇文章:CSS中重要的BFC學習

3.1 自身margin合併的狀況

  • 加個padding或者border-top/border-bottom

3.2 相鄰元素的狀況

  1. 相鄰元素中間添加一個1px的間隔元素(不推介,由於添加了冗餘標籤)
  2. 相鄰元素加上display: inline-block; 或者gridinline-grid後相鄰元素之間的垂直外邊距不會合並,不過注意grid的瀏覽器兼容性不太好。
  3. 相鄰元素能夠在其中一個元素外面包一層div,並設置任何能觸發BFC的屬性便可。codepen的DEMO
  4. 浮動與絕對定位之類脫離文檔流的元素不發生margin合併

3.3 父子元素的狀況

  1. 給父元素添加padding-top值,缺點:增長了一點padding的偏差
  2. 給父元素添加border值,好比border-top:1px solid transparent;,缺點同上
  3. 給父元素或者子元素聲明浮動float,缺點:float有時是沒必要要的。
  4. 使父元素或子元素聲明爲絕對定位:position:absolute/fixed;
  5. 給父元素添加屬性 overflow:auto/auto/scroll;
  6. 子元素的margin使用父元素的padding代替

網上的帖子大多深淺不一,甚至有些先後矛盾,在下的文章都是學習過程當中的總結,若是發現錯誤,歡迎留言指出~spa

參考:code

  1. CSS外邊距合併的問題
  2. 深刻理解css中的margin屬性
  3. 深刻理解BFC和Margin Collapse

PS:歡迎你們關注個人公衆號【前端下午茶】,一塊兒加油吧~htm

另外能夠加入「前端下午茶交流羣」微信羣,長按識別下面二維碼便可加我好友,備註加羣,我拉你入羣~

相關文章
相關標籤/搜索