理解 CSS 佈局和塊級格式化上下文
CSS佈局中有一些概念是你一旦理解它那麼就會極大的提升你的CSS技能的。這篇文章是關於塊級格式化上下文的BFC。也許你從未聽說過這個術語,但是如果你曾經用CSS做過佈局,那麼你也許知道它是什麼。理解什麼是BFC,它為什麼會起作用以及如何建立一個有用的BFC可以幫助你理解CSS佈局是怎樣工作的。
在這篇文章中,我將通過一些你可能熟悉的例子解釋什麼是BFC。我將向你展示一個新的概念,當你明白什麼是BFC以及你為什麼需要它的時候,它才真正有意義。
什麼是 BFC?
最容易明白一個BFC表現的是一個浮動的例子。在下面的例子中有一個盒模型,其中包含一張左浮動的圖和一些文字。如果我們有大量的文字,它環繞在浮動的影象上,則邊框會圍繞著整個區域。
圖1:文字環繞著浮動元素
如果刪除了一些文字,那麼文字就不足以環繞影象,並且因為圖片浮動脫離了文件流,邊框就會在圖片下面並且上升到文字的高度。
圖2:沒有足夠的文字,邊框就不能到達浮動元素所期望的高度
這是因為當我們在浮動一個元素時,文字所在的盒模型仍然是固定的高度,而因浮動元素而縮短的空間是文字的行框。這就是為什麼背景和邊框會出現在浮動元素的後面。
這裡有兩種我們通常修復這種問題的方式。一種是使用清除浮動clearfix hack1,它是通過在文字和圖片下面插入一個元素並且設定清除兩側浮動來起作用的。另一種方式是使用overflow屬性,使用其他的值來代替預設的visible。
圖3:使用 overflow:auto 使盒模型中包含浮動
overflow屬性起作用的原因是使用任何一個其他值來代替初始值visible,從而建立一個BFC。即BFC的一個特點就是它包含浮動。
BFC 佈局是一個迷你佈局
你可以認為BFC在網頁中是一個迷你佈局。一旦一個元素建立的BFC,所有東西都包含在裡面了。正如我們所看到的,它包含浮動元素使其不再超出盒子底部。同時BFC也產生了一些其他有用的行為。
BFC 防止外邊距塌陷
理解外邊距塌陷是另一個被低估的CSS技能。在下一個例子中,有一個灰色背景的div。這個div中有兩個段落。外層div有40px的下邊距;每一個段落也分別有20px的上下邊距。
由於p元素的外邊距和外層div的外邊距之間沒有任何東西而導致它們摺疊,使p段落最後會與盒子的頂部和底部平齊。所以在p段落的上面和下面我們沒有看到任何灰色。
圖4:外邊距塌陷導致在盒子的頂部和底部看不到任何灰色
如果我們對盒模型應用BFC,那麼它將包括段落和邊距並使之不會塌陷,所以我們將在邊距的後面看到灰色的背景。
圖5:使用BFC外邊距將不會塌陷
BFC再一次使元素包含在其中,阻止其外邊距塌陷或超出盒模型。
BFC 阻止內容環繞浮動元素。
你也會熟悉BFC這種行為,就是它如何在使用浮動的多列布局中工作的。如果一個專案建立了BFC,那麼它將不會環繞任何浮動元素,比如在下面的示例中有這樣的標記:
帶有float類的元素開始浮動,然後div中的文字會環繞在浮動元素周圍。
圖6:文字環繞浮動元素
那麼可以使用通過對文字使用BFC來阻止其環繞行為。
圖7:div 包含的文字使用了 BFC 使之停止環繞
這是我們建立多列浮動佈局常用的方式。浮動一個元素同時也為另一個元素建立了BFC,所以當右邊的元素比左邊高時,建立的列也不再嘗試環繞對方。
還有什麼方式可以建立 BFC?
除了使用overflow屬性以外,其他一些CSS屬性也可以建立BFC。正如我們看到的,浮動一個元素也建立了BFC,所以浮動專案將包含裡面的任何元素。
其他方式還有使用position: absolute,,使用display: inline-block,display: table-cell及display: table-caption,其中table-cell以及table-captions是HTML元素的預設屬性,所以如果有一個table資料,那麼它的每個格子都將建立BFC。column-span: all多被使用在多列布局中。Flex和Grid專案也會建立類似的BFC,它們分別被描述為Flex格式化上下文和Grid格式化上下文,這分別反映了不同的佈局型別。BFC表示塊級佈局,FFC代表Flex佈局。在實際專案中結果是一樣的,都是包含浮動並且外邊距不會發生塌陷。
建立 BFC 新方式
使用overflow屬性或其他方式建立BFC有兩個問題。第一,這些方法對於它們真正的用途會產生副作用。使用overflow屬性建立一個BFC並且包含浮動,但是在某些情況下你可能會發現得到一個了不必要的滾動條,或者陰影被剪掉了。這是由於overflow屬性本質上是告訴瀏覽器在溢位的情況下應該怎樣做—產生滾動條或者剪掉元素。瀏覽器實際上做了你讓它做的工作!
即使在沒有任何副作用的情況下,使用overflow屬性也可能會讓另一個開發人員感到困惑。為什麼overflow屬性設定為自動或滾動?開發者最初的目的是什麼?他們希望在這個元件上使用滾動條嗎?怎樣建立一個BFC是行之有效的?應該是沒有造成其他行為而創造出迷你的佈局, 或者保證是在安全範圍內的,它將不會引發任何意想不到的問題,並且開發人員的意圖也很清晰。CSS工作組認為有一個很方便的新的display屬性:flow-root。
你可以在任何情況下使用display: flow-root,它將會建立一個新的有用的BFC,它包含浮動,阻止外邊距塌陷,並且阻止元素環繞浮動。
你可以在下面的 CodePen 中看到上述所有的這些, 如果你的瀏覽器支援display: flow-root的話,如目前流行的火狐或谷歌瀏覽器。
圖8:支援 display: flow-root 屬性的瀏覽器
支援這個屬性的瀏覽器是有限的,但如果你認為這將是方便的,你可以去支援它。然而,即使目前你不能夠在你的程式碼很流利的使用flow-root功能,但你現在明白了BFC是什麼,以及當你使用overflow屬性或其它方法包含浮動的時候你明白了你在做什麼。瞭解這樣一個事實:比如BFC將阻止元素環繞浮動,這在不支援的瀏覽器中想建立Flex或Grid佈局的時候都是非常有用的。
你已經瞭解了一些關於瀏覽器如何佈置Web頁面的基本原理,這看起來似乎無關緊要,但卻可以加快建立和除錯CSS佈局的時間。
最後
“相信有很多想學前端的小夥伴,今年年初我花了一個月整理了一份最適合2018年學習的web前端乾貨,從最基礎的HTML+CSS+JS到移動端HTML5等都有整理,送給每一位前端小夥伴,53763,1707這裡是小白聚集地,歡迎初學和進階中的小夥伴。”
祝大家早日學有所成,拿到滿意offer,快速升職加薪,走上人生巔峰。