CSS中的BFC,外邊距摺疊,清除浮動

BFC是什麼?

BFC(Block Formatting Context)直譯爲「塊級格式化範圍 」。css

是 W3C CSS 2.1 規範中的一個概念,它決定了元素如何對其內容進行定位,以及與其餘元素的關係和相互做用。當涉及到可視化佈局的時候,Block Formatting Context提供了一個環境,HTML元素在這個環境中按照必定規則進行佈局。一個環境中的元素不會影響到其它環境中的佈局。html

BFC 的特徵

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

在BFC中,每個盒子的左外邊緣(margin-left)會觸碰到容器的左邊緣(border-left)(對於從右到左的格式來講,則觸碰到右邊緣)。佈局

BFC中的元素的佈局是不受外界的影響(咱們每每利用這個特性來消除浮動元素對其非浮動的兄弟元素和其子元素帶來的影響。)而且在一個BFC中,塊盒與行盒(行盒由一行中全部的內聯元素所組成)都會垂直的沿着其父元素的邊框排列。post

計算BFC的高度時,浮動元素也參與計算(可用於解決浮動形成的高度塌陷問題)flex

BFC的區域不會與float box重疊(解決浮動元素文字環繞問題)spa

觸發BFC

  • float 的值不爲nonecode

  • position 的值不爲static或者relativeorm

  • display的值爲 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一個htm

  • overflow的值不爲visible
    知足上述條件中至少一項,便可觸發 BFC

使用場景

一、外邊距摺疊問題

摺疊的條件:兩個元素的 margin 必須是 相鄰 的;兩個 margin 是鄰接的必須知足如下條件:

  • 必須是處於常規文檔流(非float和絕對定位)的塊級盒子,而且處於同一個 BFC 當中。

  • 沒有inline盒子,沒有空隙,沒有 padding 和 border 將他們分隔開。

  • 都屬於垂直方向上相鄰的外邊距。
    以下:

<div clss="container">
    <div class="f-block">
    </div>
    <div class="s-block">
    </div>
</div>
.f-block
{
  width:200px;
  height:200px;
  background-color:silver;
  margin:10px;
}
.s-block
{
  width:200px;
  height:200px;
  background-color:silver;
  margin:10px;
}

解決方法:
破壞產生摺疊的條件便可:
一、給元素添加浮動或者絕對定位(會影響總體佈局,改動大)
二、將元素改成行內元素(會影響總體佈局,改動大)
三、元素間插入一個高度大於0的div
四、使元素不在同一BFC中

<!--元素間插入一個高度大於0的div-->
  <div class="f-block">
  </div>
  <div style="height:0.01px"></div>
  <div class="s-block">
  </div>

元素間插入一個高度大於0的div

<div class="f-block"></div>
<div>
  <div class="s-block"></div>
</div>

f-block,s-block以及s-block外層div已經仍是處在相同BFC中,因此仍是會產生外邊距摺疊。這裏產生的摺疊比較複雜:
首先是s-block和外層div的外邊距摺疊,而後是合併後的摺疊外邊距再與f-block產生外邊距摺疊。
下面解決父子元素的外邊距摺疊問題:

給父元素添加padding 或 border(破壞外邊距摺疊條件)

<div class="f-block"></div>
<div style="background-color:red;border:1px solid black">
  <div class="s-block"></div>
</div>

給父元素建立新的塊級格式化上下文(建立了新的塊級格式化上下文的塊元素,不與它的子元素髮生margin 摺疊)

<div class="f-block"></div>
<div style="background-color:red;overflow:hidden">
  <div class="s-block"></div>
</div>

二、清除浮動

<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
.container
{
  width:550px;
  border:5px solid red;
}
.item
{
  width:100px;
  height:100px;
  float:left;
  background-color:silver;
  margin:5px;
}

對於上面的代碼,咱們但願獲得這樣的結果:

但結果倒是這樣的:

緣由是由於浮動元素脫離文檔流,container的高度沒法被撐開。

清除浮動的方法及原理:

clear屬性
clear屬性的意義就是禁止特定方向上存在浮動元素,例如clear: left就是不容許元素左方存在文檔流以前浮動元素(注意,這裏左邊若是存在文檔流以後的浮動元素是沒法清理的)
根據CSS權威指南,具體的實現原理是經過引入清除區域,這個至關於加了一塊看不見的框把定義clear屬性的元素向下擠,直到元素指定方向恰好沒有浮動元素,這樣看起來包含框就把浮動框給包含了,實際上浮動框脫離文本流的性質沒變,它們依然是「浮」在上面的
用法:
一、容器內結尾處加空div標籤 clear:both
二、容器定義僞類:after 和 zoom(IE8以上和非IE瀏覽器才支持:after,原理和方法2有點相似,zoom(IE轉有屬性)可解決ie6,ie7浮動問題)

.container:after{display:block;clear:both;content:"";visibility:hidden;height:0}
.container{zoom:1}

容器造成新BFC
計算BFC的高度時,浮動元素也參與計算

.container
{
  width:550px;
  border:5px solid red;
  overfow:hidden;
}

或者使容器自身浮動也能夠

消除浮動引發的文字環繞效果:

<div class="box">
    <div class="img">image</div>
    <div class="info">信息信息信息信息信息信息信息信息信息信息信息信信息信息信息信息信息信息信息信息信息信息信息信信息信息信息信息信息信息信息信息信息信息信息信信息信息信息信息信息信息信息信息信息信息信息信</div>
</div>
.box {width:210px;border: 1px solid #000;float: left;} 
.img {width: 100px;height: 100px;background: #696;float: left;} 
.info {background: #ccc;color: #fff;}

帶有浮動屬性的元素會脫離標準流進行排列布局,脫離標準流後的元素就不和塊元素相處在同一個流不居中,使得帶有浮動屬性的元素漂浮在正常塊元素上面。可是浮動的塊雖然脫離了正常的文檔流,可是依然佔據正常文檔流的文本空間。因而在其後面寫的文本並不會被浮動元素所覆蓋而是繼續水平排列超出換行。
標準流中塊元素每一個各佔一行。內聯元素則是水平排列,直到一行排列不下進行換行操做。由於使用了float的元素佔據文本空間,使得後面的文本以除了浮動元素以外的空間爲排列基準,造成了文本環繞的效果。

清除環繞效果就是使info造成一個新的BFC(BFC的區域不會與float box重疊),添加overflow:hidden便可。
注意:給info絕對定位也會造成一個新的BFC,可是info會按照絕對定位的規則進行佈局,會與img重疊。

參考文章
深刻理解BFC和Margin Collapse
細說CSS中的BFC

相關文章
相關標籤/搜索