這是我找到講解 格式化上下文 (Block Formatting Context, BFC)
最棒的文章之一(下文統稱 BFC
),因爲 BFC
困擾我良久,但願這篇翻譯能讓 BFC
再也不困擾你們。css
翻譯是機翻 + 修改,會有刪減,另外強烈推薦閱讀原文。html
原文地址:www.smashingmagazine.com/2017/12/und…web
你可能從沒聽過「塊格式化上下文」,可是若是你曾經用CSS作過佈局,你可能就知道它是什麼。本文將會講述如何建立塊格式化上下文,以及爲何它在CSS佈局中很重要,並向展現建立塊格式化上下文的新方法。瀏覽器
有些概念一旦理解會確確實實增長你的CSS技能熟練度,而理解 BFC
以及知道如何建立 BFC
很是有用,能夠幫助加深對CSS佈局的理解。這篇文章會有豐富且常見的例子幫助你理解 BFC
,並解釋爲何你須要 BFC
。安全
只要經過一個簡單的浮動佈局的例子就能夠理解 BFC
的行爲。在下面的示例中,有一個 div
,div
裏包含一個 向左浮動的div
和 一些文本
。若是文本足夠多,就會環繞浮動元素,而後環繞整個區域。ide
<div class="outer">
<div class="float">I am a floated element.</div>
I am text inside the outer box.
</div>
複製代碼
.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;
}
複製代碼
若是刪除一些文本內容,那麼就沒有足夠的內容來包圍浮動元素,並且因爲浮動是脫離文檔流的,因此邊框高度會變矮,只有到包含到文本的高度。即高度坍塌。佈局
這是由於當咱們浮動一個元素時,文本所在的框的寬度保持不變,爲了給浮動元素騰出空間而縮短的是文本的空間。ui
咱們一般有兩種方法來解決這個佈局問題。一種方法是使用 clearfix hack
(即清除浮動),它的做用是在文本和圖像下面插入一個元素,並將其設置爲 clear: both;
。另外一種方法是使用 overflow
屬性,將其值改成 visible
之外的便可。spa
.outer {
overflow: auto;
}
複製代碼
overflow: auto
令外部的div包含浮動元素另外,能夠在CODEPEN中查看效果:codepen.io/rachelandre…翻譯
overflow
以這種方式工做的緣由是,使用 除visible初值之外
的任何值都會建立一個 BFC
,而 BFC
的特性之一就是它能夠包裹浮動元素。
譯者注:重點之一, BFC
能夠包裹浮動元素。即讓浮動元素 看起來沒有脫離文檔流同樣
,佔據着其寬高大小的位置。
能夠把 BFC
想象成頁面內的迷你佈局。一旦一個元素建立了一個 BFC ,全部的東西都包含在它裏面。
正如咱們所看到的,包括浮動元素,它們再也不從盒子的底部伸出。 BFC
也會有一些其餘有用的行爲。
理解邊距坍塌是另外一個被低估的CSS技能。在下一個示例中,有一個背景顏色爲灰色的div。
這個div包含兩個段落。外部div元素的頁邊距離底部40像素;段落的上下邊距邊都是20像素。
.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的頁邊距之間沒有任何內容,這兩個元素將摺疊起來,所以段落最終與框的頂部和底部齊平。咱們在段落的上面和下面沒有看到灰色背景。
若是咱們爲外部div元素建立一個 BFC
,它就會包含段落和它們的邊距,這樣它們就不會摺疊,咱們能夠看到邊距後面容器的灰色背景。
.outer {
background-color: #ccc;
margin: 0 0 40px 0;
overflow: auto; /* 建立BFC,參考:https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context */
}
複製代碼
在CODEPEN中查看代碼:codepen.io/rachelandre…
(譯者注:在理解BFC以前,我都是在外部元素裏設置padding實現一樣的效果!)
再次說明, BFC
的工做是把東西裝在盒子裏,而且防止它們從盒子裏跑出來。
BFC
可讓內容再也不包裹浮動元素。您還將熟悉 BFC
的這種行爲,由於使用浮動的任何列類型佈局都是這樣工做的。
若是一個項建立了一個 BFC
,那麼該項目將不會包裹任何浮動元素。在下面的例子中,有這樣的標記:
<div class="outer">
<div class="float">I am a floated element.</div>
<div class="text">I am text</div>
</div>
複製代碼
帶有 float類
的項會向左浮動,所以div中的文本在它環繞 float
以後。
咱們能夠經過將包裹文本的div設置爲BFC來防止這種環繞行爲。
.text {
overflow: auto;
}
複製代碼
text
類的div如今是 BFC
,所以文本不會換行這實際上就是建立多個列浮動佈局的方法。浮動項還爲該項建立了一個BFC,所以,就算右邊的列比左邊的列高,各個列也不會相互環繞。
在CODEPEN中查看代碼:codepen.io/rachelandre…
除了使用 overflow
建立 BFC
外,其餘一些CSS屬性還建立 BFC
。正如咱們所看到的,浮動元素建立了 BFC
。你的浮動項將包含它裏面的任何東西。
在元素中使用position: absolute
或者 position: fixed
使用 display: inline-block
、 display: table-cell
或 display: table- title
。表單元格和表標題是這些HTML元素的默認設置,所以,若是有一個 table
,每一個單元格都將建立一個 BFC
。
使用 column-span: all
,用於跨多列布局的列。 Flex
和 Grid
的項還建立了相似於 BFC
的東西,只不過它們分別被描述爲 Flex格式化上下文(Flex Formatting Context, FFC)
和 網格格式化上下文(Grid Formatting Context, GFC)
。這反映了每一個項參與的佈局類型。 塊格式化上下文BFC
表示項正在參與塊佈局,而 Flex格式化上下文
表示項正在參與Flex佈局。在實際中,結果是相同的,浮動也能夠被包含而且元素的 margin
邊界不會坍塌。
使用 overflow
或其餘方法建立 BFC
有兩個問題。首先,這些方法的反作用是基於它們真正的設計目的。 overflow
方法建立一個 BFC
幷包含浮動元素,可是在某些狀況下,你會發現你獲得了一個不須要的滾動條,或者陰影被剪切了。這是由於設計 overflow
屬性的目的是讓您告訴瀏覽器在溢出的狀況下應該作什麼——致使滾動條或剪切內容。瀏覽器正在作你讓它作的事情!
即便在沒有任何不想要的反作用的狀況下,使用 overflow
也可能會讓其餘開發人員感到困惑。爲何 overflow
設置爲自動或滾動?最初的開發者的意圖是什麼?他們想要這個組件上的滾動條嗎?
另外一個很是有用的建立 BFC
的方法是令其是惰性的,除了建立那個小布局和在其中安全地發生事情的能力以外,不會致使其餘行爲。該方法不會引發任何意外的問題,而且容許清楚地說明開發人員的意圖。CSS工做組認爲這可能也很是方便,所以咱們有了 display
屬性的一個新值—— flow-root
。
若是您有一個支持 display: flow-root
(如最新的Firefox或Chrome)的瀏覽器,您能夠在下面的代碼頁中看到全部這些。
CODEPEN代碼頁面:codepen.io/rachelandre…
display: flow-root
的瀏覽器支持狀況瀏覽器對這個屬性的支持是有限的,但支持還在增長,若是你認爲它會很方便,必定要去給它投票。可是,即便你如今不能在代碼中使用方便的 flow-root
特性,你如今也瞭解了什麼是 BFC
,以及當你使用 overflow
或其餘方法來包裹浮動元素時能夠清楚的知道你在作什麼。
你已經瞭解了關於瀏覽器如何佈局web頁面的一些很是基本的知識。雖然它們自己看起來可有可無,但正是這些小知識能夠加快建立和調試CSS佈局所需的時間。