css外邊距摺疊(margin collapsing)

前文

這是的一個經典的老問題,由於以前恰好有讀者朋友問到,順便整理一下。segmentfault

從一個簡單例子提及

先看一個簡單示例:瀏覽器

<style>
    .slide1 p {
      margin:10px 0;
    }
  </style>
 <div class="slide1">
    <h3>第1種外邊距摺疊:兄弟元素</h3>
    <p>文本上下間距10px</p>
    <p>文本上下間距10px</p>
  </div>

狀況1
狀況2

看這個例子中的兩個p標籤,根據樣式定義:第一個pmargin-bottom和第二個pmargin-top 都是10px,那實際距離應該等於20px纔對,可是用瀏覽器查看一下能夠發現,最終的邊距是10px。 這個例子就是外邊距摺疊:塊級元素的上外邊距和下外邊距有時會合並(或摺疊)爲一個外邊距。ide

分類狀況

外邊距摺疊有3種基本狀況:spa

  1. 相鄰元素
  2. 父元素和第一個子元素(或者最後一個子元素,等下記得回頭思考下這裏爲啥是第一個或者最後一個)
  3. 空的塊級元素

先不急着記憶,首先,前文的例子中就是第一種狀況--相鄰的兩個元素之間發生的外邊距摺疊。
第二種狀況以下:
狀況2code

<style>
    .father {
      background-color: green;

    }
    .child {
      margin-top: 50px;
      background-color: red;
      height: 300px;
    }
  </style>
  <h3>第2種外邊距摺疊:父元素和首個子元素</h3>
  <div class="slide2 father">
    <!-- 父元素是綠色 -->
    <div class="slide2 child">
      <!-- 子元素是紅色 -->
    </div>
  </div>

如圖:blog

  • 狀況2: 子元素的外邊距會「轉移」到父元素的外面

第三種稍微有點特殊,必須添加一個輔助的塊級元素才能看到空元素的摺疊狀況(原文這裏有遺漏,感謝評論區摩天大樓的指出),以下:圖片

<style>
    .slide3 {
    margin: 10px 0;
  }
</style>

<body>
    <h3>第3種外邊距摺疊:空的塊級元素</h3>
    <div class="slide3"></div>
    <div style="background: #063181;color: #fff;">這是用來檢測slide3已經摺疊的輔助元素</div>
</body>

圖片描述

  • 狀況3:該元素的上下外邊距會摺疊

好了,到這裏咱們不妨來看看這幾種狀況的共同點(建議畫一下他們的盒模型,我懶就不畫了-_-),能夠發現發生外邊距摺疊的共同緣由:margin之間直接接觸,沒有阻隔get

如何理解直接接觸?很簡單:it

  • 第一個例子中,兩個<p>標籤的垂直方向margin是直接接觸的;
  • 第二個例子中,因爲父元素的padding,border都爲0,因此margin和它的子元素也是直接接觸的。(這個例子畫出盒模型就很好理解)
  • 第三個例子中,空元素自己的上下邊距也是直接接觸的(padding,border也是0)

各類狀況下摺疊的結果

摺疊後的邊距如何計算,這個能夠簡單驗證下:table

  1. 若是兩個外邊距都是正值,摺疊後的邊距取較大的一個
  2. 若是兩個邊距一正一負,摺疊後的邊距爲邊距之和
  3. 若是兩個邊距都爲負數,摺疊後邊距爲較小的邊距之和

如何防止外邊距摺疊

前文說到,發生外邊距摺疊的緣由是,外邊距直接接觸,所以防止摺疊的方式就是,阻隔這個直接接觸,組合的方法包括:

  1. 嵌套狀況只要border padding 非0,或者有inline元素隔開,好比父元素里加一行文字也能夠(能夠直接在狀況2嘗試)
  2. 任何藉助bfc造成阻隔的方式,如浮動,display:table等(BFC不熟悉的同窗先查查,我後面補上)

小結

還得補充一下,前面討論的是基本狀況,在基本狀況下還能夠進行組合,好比多個相鄰元素之間;多層後代元素嵌套等等,弄明白基本原理,其餘狀況只要寫寫小的demo驗證下就很好理解了。而後是慣例:若是內容有錯誤的地方歡迎指出(以爲看着不理解不舒服想吐槽也徹底沒問題);若是對你有幫助,歡迎點贊和收藏,轉載請徵得贊成後著明出處,若是有問題也歡迎私信交流,主頁有郵箱地址

相關文章
相關標籤/搜索