1. 程式人生 > >詳解css外邊距摺疊(margin collapsing)

詳解css外邊距摺疊(margin collapsing)

外邊距摺疊指的是毗鄰的兩個或多個外邊距 (margin) 會合併成一個外邊距,本文詳細的介紹了一下css外邊距摺疊的實現,分為3種情況,非常具有實用價值,需要的朋友可以參考下

前文

這是的一個經典的老問題,因為之前剛好有讀者朋友問到,順便整理一下。

從一個簡單例子說起

先看一個簡單示例:

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

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

分類情況

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

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

先不急著記憶,首先,前文的例子中就是第一種情況--相鄰的兩個元素之間發生的外邊距摺疊。

第二種和第三種情況如下:

`<``style``>`
`.father {`
`background-color: green;`
`}`
`.child {`
`margin-top: 50px;`
`background-color: red;`
`height: 300px;`
`}`
`.slide3 {`
`margin: 10px 0;`
`}`
`</``style``>`
`<``h3``>第2種外邊距摺疊:父元素和首個子元素</``h3``>`
`<``div` `class``=``"slide2 father"``>`
`<!-- 父元素是綠色 -->`
`<``div` `class``=``"slide2 child"``>`
`<!-- 子元素是紅色 -->`
`</``div``>`
`</``div``>`
`<``h3``>第3種外邊距摺疊:空的塊級元素</``h3``>`
`<``div` `class``=``"slide3"``></``div``>`
      }//歡迎加入全棧開發交流划水交流圈:582735936
    ]//面向划水1-3年前端人員
  }   //幫助突破划水瓶頸,提升思維能力

他們的影象也分別如圖:

情況2: 子元素的外邊距會“轉移”到父元素的外面
情況3:該元素的上下外邊距會摺疊

好了,到這裡我們不妨來看看這幾種情況的共同點(建議畫一下他們的盒模型,我懶就不畫了-_-),可以發現發生外邊距摺疊的共同原因:margin之間直接接觸,沒有阻隔。

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

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

各種情況下摺疊的結果

摺疊後的邊距如何計算,這個可以簡單驗證下:

  • 如果兩個外邊距都是正值,摺疊後的邊距取較大的一個
  • 如果兩個邊距一正一負,摺疊後的邊距為邊距之和
  • 如果兩個邊距都為負數,摺疊後邊距為較小的邊距之和

如何防止外邊距摺疊

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

  • 巢狀情況只要border padding非0,或者有inline元素隔開,比如父元素里加一行文字也可以(可以直接在情況2嘗試)
  • 任何藉助bfc形成阻隔的方式,如浮動,display:table等(BFC不熟悉的同學先查查,我後面補上)

小結

還得補充一下,前面討論的是基本情況,在基本情況下還可以進行組合,比如多個相鄰元素之間;多層後代元素巢狀等等,弄明白基本原理,其他情況只要寫寫小的demo驗證下就很好理解了。然後是慣例:如果內容有錯誤的地方歡迎指出(覺得看著不理解不舒服想吐槽也完全沒問題);

以上就是本文的全部內容,希望對大家的學習有所幫助,