外邊距重疊

學習HTML的時候遇到過這種情況:

兩個塊級box垂直方向相鄰,如果設置它們的上下margin,就會發生重疊(margin塌陷)現象。

當時也沒有想太多,只知道有這種情況,在使用的時候會盡量設置單個margin或者設置padding值,來避免出現重疊現象,但閑下來時,我仔細想了下這個問題,然后查詢了一些資料,結果引出來一個東西 BFC

BFC

什么是BFC?

要了解什么是BFC,就要涉及一些CSS布局的一些基本概念,其中塊級盒的概念要清楚。

盒模型

在W3C規定里,完整的盒模型為:


  • content:內容(主體)
  • padding:內邊距
  • border:邊框
  • margin:外邊距

每個塊級元素都會自動生成一個塊級盒block-level box,每個塊級盒的盒模型結構都如上圖盒模型一樣。
其中,margin、padding、border、content分別定義了元素的四種邊,每種類型的邊定義了一種盒子,分別是margin box、padding box、border box 、content box。而控制塊級盒之間的垂直間距的就是margin box。
我們對塊級元素布局的描述為:

普通流中的塊元素獨占一行,然后從上往下一個接一個的排布,相鄰元素間會有外邊距折疊

為什么會是這種布局呢?原因就是BFC的存在

BFC定義

BFC(Block formatting context)直譯為"塊級格式化上下文"。它是一個獨立的渲染區域,只有Block-level box參與, 它規定了內部的Block-level Box如何布局,并且與這個區域外部毫不相干。

BFC布局規則(重點)

  • 內部的Box會在垂直方向,一個接一個地放置。
  • Box垂直方向的距離由margin決定。屬于同一個BFC的兩個相鄰Box的margin會發生重疊
  • 每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對于從左往右的格式化,否則相反)。即使存在浮動也是如此。
  • BFC的區域不會與float box重疊。
  • BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此。
  • 計算BFC的高度時,浮動元素也參與計算

觸發(創建)BFC

  • float的值不為none
  • overflow的值為auto、scroll或hidden。
  • display的值為inline-block, table-cell, table-caption, flex, inline-flex中的任何一個。
  • position的值不為relative和static(可以為absolute或fixed)

BFC功能和作用

1. 自適應左右兩欄布局

代碼:

     <style>
         html,body{
             width: 100%;
             height: 100%;
         }
       .box1{
           width: 180px;
           height: 300px;
           background-color: purple;
           float: left;
       }
         .box2{
             height: 100%;
             background-color: yellow;
         }
     </style>
<body>
<div class="box1"></div>
<div class="box2"></div>
</body>

顯示效果:


根據BFC布局規則:

每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對于從左往右的格式化,否則相反)。即使存在浮動也是如此。

因此,即時存在浮動元素box1,但box2的左邊依然緊貼父元素左邊界。

如何實現左右兩欄分布?
根據BFC布局規則:

BFC的區域不會與float box重疊

可以設置box2為BFC,觸發BFC效果,實現自適應兩欄布局。

.box2{
             height: 100%;
             background-color: yellow;
             overflow: hidden;
         }

當觸發box2生成BFC后,這個新的BFC就不會與浮動的box1重疊。因此box2會根據包含塊(父元素)的寬度,和box1的寬度,自動變窄(自適應)。效果如下:


清除內部浮動

代碼:

     <style>
         html,body{
             width: 100%;
             height: 100%;
         }
         .father{
           width: 200px;
           border:8px solid #d02c38;
         }
         .son{
             width: 80px;
             height: 80px;
             border:5px solid #666666;
             display: inline-block;
             float: left;
         }
     </style>
<body>
<div class="father">
    <div class="son"></div>
    <div class="son"></div>
</div>
</body>

頁面顯示為:



father盒子中的son盒子全部為浮動后,內容無法撐起父盒子的高度,所以father盒子顯示為一條寬度為16px的實線,想撐起父盒子的高度,就需要清除浮動帶來的影響。
根據BFC規則:

計算BFC的高度時,浮動元素也參與計算

因此,father元素觸發BFC,那么father元素計算高度的時候,會把son元素的高度也計算進去,相當于給father設置了高度,達到清除浮動的效果。


防止垂直重疊

在文章開頭就說到,相鄰兩個塊級元素的上下margin值會發生重疊現象。現在可以通過BFC來解決這個問題。
代碼:

     <style>
         html,body{
             width: 100%;
             height: 100%;
         }
         .box1{
             width: 100px;
             height: 100px;
             background-color: red;
             margin-bottom: 50px;
         }
         .box2{
             width: 100px;
             height: 100px;
             background-color: blue;
             margin-top: 50px;
         }
     </style>
<body>
<div class="box1">box1</div>
<div class="box2">box2</div>
</body>

效果顯示:

兩個盒子之間的距離設置上下各50px,按我們理解的來算應該是100px,但實際上是50px,外邊距發生了重疊。
根據BFC規則:

Box垂直方向的距離由margin決定。屬于同一個BFC的兩個相鄰Box的margin會發生重疊

我們可以把這兩個盒子設為不同的BFC,就能避免重疊。實際是給下面的盒子box2設置屬性:

.box2{
             width: 100px;
             height: 100px;
             background-color: blue;
             margin-top: 50px;
             display: inline-block;
             /*overflow: hidden;*//在此處無效
         }

效果為:


BFC的這些作用,都體現了BFC的最大的規則屬性:

BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此。

因為BFC內部的元素和外部的元素絕對不會互相影響,因此, 當BFC外部存在浮動時,它不應該影響BFC內部Box的布局,BFC會通過變窄,而不與浮動有重疊。同樣的,當BFC內部有浮動時,為了不影響外部元素的布局,BFC計算高度時會包括浮動的高度。避免margin重疊,也是這樣的一個道理。

參考文章:
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,786評論 1 92
  • relative:生成相對定位的元素,通過top,bottom,left,right的位置相對于其正常位置進行定位...
    zx9426閱讀 963評論 0 2
  • 大家好~ 我是一枚正直純潔的苦逼程序員!!!!! 兩個或多個塊級盒子的垂直相鄰邊界會重合。結果的邊界寬度是相鄰邊界...
    啊啊啊滿閱讀 1,047評論 0 1
  • 1.在什么場景下會出現外邊距合并?如何合并?如何不讓相鄰元素外邊距合并?給個父子外邊距合并的范例 概念:在CSS當...
    饑人谷_任磊閱讀 670評論 0 3
  • 浮動元素有什么特征?對父容器、其他浮動元素、普通元素、文字分別有什么影響?## 特征:浮動模型也是一種可視化格式模...
    饑人谷_zhangfan閱讀 288評論 0 0