理解CSS佈局和塊格式化上下文

在進行html佈局及css編寫的時候,你是否遇到過這樣的問題:css

  • 子元素設置浮動脫離文檔流後,父元素沒法將其徹底包裹
  • 子元素浮動實現兩欄佈局時,另外一個子元素與浮動子元素重疊
  • 垂直方向的外邊距margin重疊 ...

一般咱們使用塊級格式化上下文(BFC)就能解決。html

什麼是BFC?

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

FC(formatting context)直譯過來是格式化上下文,它是頁面中的一塊渲染區域,有一套渲染規則,決定了其子元素如何佈局,以及和其餘元素之間的關係和做用。瀏覽器

BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素,而且容器元素不會影響兄弟元素的佈局。安全

什麼狀況下會建立BFC

  • 根元素或包含根元素的元素
  • 浮動元素(元素的 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,即便該元素沒有包裹在一個多列容器中。

常見應用場景

使父元素包含浮動元素

下面例子解釋如何讓浮動內容和父元素等高,清楚浮動負面影響bash

htmlide

<div class="outer">
  <div class="float">I am a floated element.</div>
  I am text inside the outer box.
</div>
複製代碼

css佈局

.outer {
  border: 5px dotted rgb(214,129,137);
  border-radius: 5px;
  width: 450px;
  padding: 10px;
  margin-bottom: 40px;
}

.float {
  padding: 10px;
  border: 5px solid rgba(214,129,137,.4);
  border-radius: 5px;
  background-color: rgba(233,78,119,.4);
  color: #fff;
  float: left;  
  width: 200px;
  margin: 0 20px 0 0;
}
複製代碼

經過給左側文字設置向左浮動實現文字環繞效果是很常見的作法,當文本足夠長時,會看到以下效果,父元素能夠徹底包裹子元素。flex

image

但事實上,float中的文字已經脫離文檔,若是文檔流文字過少,浮動元素就會溢出父元素邊緣。ui

enter image description here

這時候爲父元素設置overflow: auto或者除invisible默認值以外的任何有效值都能建立BFC解決這個問題,使父元素包含浮動元素

.outer {
  overflow: auto;
}
複製代碼

enter image description here

BFC防止垂直外邊距重疊

外邊距摺疊的規則是:當兩個塊級元素相鄰而且在同一個塊級格式化上下文時,它們垂直方向上的外邊距會產生重疊

html

<div class="outer">
  <p>I am paragraph one and I have a margin top and bottom of 20px</p>
  <p>I am paragraph two and I have a margin top and bottom of 20px</p>
</div>
複製代碼

css

.outer {
  background-color: #ccc;
  margin: 0 0 40px 0;
}

p {
  padding: 0;
  margin: 20px 0 20px 0;
  background-color: rgb(233,78,119);
  color: #fff;
}
複製代碼

因爲p元素的邊緣和外部div上的邊距之間沒有內容,所以二者將會合並,所以段落最終與框的頂部和底部齊平。咱們在段落的上方和下方看不到任何灰色。以下圖:

enter image description here

當父元素設置了BFC以後,父元素與子元素p重疊區域將再也不合並

.outer {
  background-color: #ccc;
  margin: 0 0 40px 0;
  overflow: auto;
}
複製代碼

enter image description here

BFC防止文本環繞

依然像上面例子文字環繞效果的佈局和樣式

html

<div class="outer">
  <div class="float">I am a floated element.</div>
  <div class="text">I am text...</div>
</div>
複製代碼

css

.float{
    float: left;
}
複製代碼

enter image description here

這時候若是不想要右側文字環繞浮動文字盒子,在左側div設置浮動的狀況下,我能夠經過使右邊div成爲BFC,使兩個兄弟div互相隔離、互不影響,從而達到去除文字環繞的效果。

.text {
  overflow: auto;
}
複製代碼

enter image description here

建立BFC的新方式

建立BFC的許多方法一般會帶來一些反作用,目前爲止彷佛最安全的就是overflow屬性,但某些狀況下咱們不須要滾動條,此時滾動條就變成了這種方式的反作用,所以display有個新的屬性flow-root能夠在任何須要建立BFC場景下使用,它而且不會帶來任何反作用。

flow-root瀏覽器兼容狀況:

enter image description here

瀏覽器對此值的支持是有限的,若是要在不支持flex或網格佈局瀏覽器建立回退,瞭解BFC阻止浮動元素的負面影響十分必要。

PS:更多前端資訊、技術乾貨,請關注公衆號「前端新視界

前端新視界
相關文章
相關標籤/搜索