從頭開始複習css之BFC

夏天快到了,又到了白大腿橫飛的時代。坐下來摸了摸腰間殘留的今年五花肉就忽然以爲時光待我並不怎麼寬厚啊。css

昨天寫了一篇關於浮動的文章,裏面就提到了BFC 並介紹了幾種利用BFC來清除浮動的方式,那麼今天來解答一下:到底什麼是BFC?html

1、 什麼是BFC?

其實你叫我單純的回答大傢什麼是BFC,我只能告訴你BFC的全稱(Block Fromatting Context)和中文翻譯名(塊級格式化上下文)。若是你叫我深刻的解釋這這個名詞,這就比如你叫我來解釋什麼叫男生/女生同樣,你們我都知道這兩個名詞,可是你叫人跟你解釋清楚倒是很麻煩,一樣bfc也是如此。程序員

1.一、 w3c對BFC的解釋

首先咱們來看看W3C對BFC的解釋 瀏覽器

w3c
我在這裏簡單的翻譯一下:(可能不怎麼標準呀)

浮動元素、絕對定位元素等非快級盒子的快級容器(例如:inline-blocks, table-cells, 和 table-captions),以及overflow屬性不爲visiable的塊級元素元素,都會其內容創建新的塊級格式化上下文。bash

在BFC(塊級格式化上下文)中,盒在垂直方向一個一個的放置,從包含塊的頂部開始,相鄰的兄弟盒子之間的垂直距離由margin屬性來決定,在同一個BFC(塊級格式化上下文)中的相鄰兄弟之間的margin會被合併。佈局

在一個BFC(塊級格式化上下文)中,最左邊的左邊距和包含塊的左邊相同(對於從右向左格式的結構,內外也是挨着的)。即便存在浮動狀況(儘管盒子的大小可能由於內部子盒子的浮動而變窄),這也成立,除非子盒子內創建了一個新的BFC(塊級格式化上下文),這種狀況下,該盒自身可能由於浮動變窄。性能

講道理,不知道是否是我翻譯的緣故,我硬是沒看懂orz! 算了咱們仍是來看一下中文版MDN對BFC的解釋吧:flex

1.二、 w3c對BFC的解釋

塊格式化上下文(Block Formatting Context,BFC) 是Web頁面的可視化CSS渲染的一部分,是塊盒子的佈局過程發生的區域,也是浮動元素與其餘元素交互的區域。ui

下列方式會建立塊格式化上下文:spa

  • 根元素或包含根元素的元素
  • 浮動元素(元素的 float 不是 none)
  • 絕對定位元素(元素的 position 爲 absolute 或 fixed)
  • 行內塊元素(元素的 display 爲 inline-block)
  • 表格單元格(元素的 display爲 table-cell,HTML表格單元格默認爲該值)
  • 表格標題(元素的 display 爲 table-caption,HTML表格標題默認爲該值)
  • 匿名錶格單元格元素(元素的 display爲 table、table-row、 table-row-group、table-header-group、table-footer-group(分別是HTML table、row、tbody、thead、tfoot的默認屬性)或 inline-table)
  • overflow 值不爲 visible 的塊元素
  • display 值爲 flow-root 的元素
  • contain 值爲 layout、content或 strict 的元素
  • 彈性元素(display爲 flex 或 inline-flex元素的直接子元素)
  • 網格元素(display爲 grid 或 inline-grid 元素的直接子元素)
  • 多列容器(元素的 column-count 或 column-width 不爲 auto,包括 column-count 爲 1)
  • column-span 爲 all 的元素始終會建立一個新的BFC,即便該元素沒有包裹在一個多列容器中(標準變動,Chrome bug)。 塊格式化上下文包含建立它的元素內部的全部內容.

塊格式化上下文對浮動定位(參見 float)與清除浮動(參見 clear)都很重要。浮動定位和清除浮動時只會應用於同一個BFC內的元素。浮動不會影響其它BFC中元素的佈局,而清除浮動只能清除同一BFC中在它前面的元素的浮動。外邊距摺疊(Margin collapsing)也只會發生在屬於同一BFC的塊級元素之間。

2、用代碼來解釋上面懵懂的話語吧

其實上面找了這麼多文檔,其實大抵仍是不怎麼懂的,可是咱們就來按照他們的說法來寫點點代碼,來看下面一段代碼:

// html
<div class="parent">
  <div class="son"></div>
</div>
// css
*{
  margin: 0;
  padding: 0;
}
.parent {
  width: 200px;
  border: 10px solid pink;
  margin:100px;
}
.son {
  width: 100px;
  height: 100px;
  background: red;
  float: left;
}
複製代碼

效果以下:

效果
這裏咱們發現因爲子元素添加了浮動屬性,致使父元素的寬度並無被撐開。那咱們按照文檔的說法,來作一下簡單的實驗:

.parent {
  width: 200px;
  border: 10px solid pink;
  margin:100px;
  /*overflow: hidden;*/
  /*display: inline-block;*/
  /*display: flex;*/
  /*display: flow-root;*/
  /*position: absolute;*/                      
  ...
}
複製代碼

這裏咱們發現了一個狀況:即便是子元素添加了浮動屬性,父元素都會被子元素撐開。這裏咱們就差很少能明白前面W3C的第一段話,使用上面一系列的屬性能讓父盒子產生BFC,我在這裏總結一下BFC的功能,就是讓父盒子包裹起子盒子來,也就能夠達到清除浮動的功能。

而後咱們在代碼的基礎上增長一個兒子來繼續探究BFC的做用:

// html
<div class="parent">
  <div class="son"></div>
  <div class="son1"></div>
</div>
// css
.son {
  width: 100px;
  height: 100px;
  background: red;
  float: left;
}
.son1 {
  width: 100px;
  height: 100px;
  background: blue;
  display: flow-root;
}
複製代碼

首先在son1中不添加display屬性的時候效果以下:

效果
此時咱們發現因爲son盒子是浮動的不佔據位置,此時son1就會霸佔son在父盒子的位置產生上面覆蓋的效果。 而後咱們加入display屬性的時候效果以下:
效果
由上面的對比效果咱們能夠明顯的發現: 每一個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此。而且相鄰BFC盒子不會重疊

這裏有這麼個東西值得你們注意的,若是我在son1盒子上面增長一個margin-left的屬性,咱們發現並無效果,直到margin-left的長度大於son盒子的時候纔會產生偏移。

效果
可是若是在son上面加一個margin-right的屬性:
效果

從上面這兩個例子能更清楚的說明相鄰BFC盒子不會重疊的特性。

緊接着咱們來繼續的探究一下垂直margin合併的問題,修改一下上面的代碼:

.son {
  width: 100px;
  height: 100px;
  background: red;
  margin: 20px;
}
.son1 {
  width: 200px;
  height: 100px;
  background: blue;
  margin: 20px;
}
複製代碼

效果
從面的效果能夠發現咱們就能夠很清楚的能夠發現: 盒子垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰子盒子的margin會發生重疊

若是想清除這種重疊效果,能夠在son1的外層套一個盒子(穿上一件馬甲),就像這樣:

效果

3、 從新梳理浮動的做用:

一、 自適應兩欄佈局 二、 清除內部浮動 三、 防止垂直 margin 重疊 總而言之:BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素。反之也如此

說在最後

今天在最後想說一下關於使用BFC特性的問題。咱們都知道CSS有一個不正交的特別。一般來講:一個屬性並非由於單獨某個效果而設計的,可能某個屬性會有各類不一樣的效果。怎麼理解?例如:overflow:hidden屬性,他不僅僅只是產生了BFC的效果,他還有一些額外的做用:當子盒子的長/寬大於父盒子的時候,就會將溢出的子元素內容給隱藏掉。若是咱們單單隻想要BFC特性的話,要選用適合場景的屬性。

可能官方看到咱們這些底層程序員的呼聲,推出了display:flow-root屬性,這個是專門用來生成BFC的,但因爲這個屬性比較新,不少瀏覽器都不能完美的支持,使用的適合也要謹慎當心。

說了這麼多,只是想讓諸位看官在開發裏面要大膽使用,仔細驗證,在項目條件支持的角度下 多去使用新的知識,畢竟時代是在不斷進步的,咱們也要不斷更新本身的知識儲備。好了,也已通過了12點了,睡覺去了。

相關文章
相關標籤/搜索