摘要:是指塊級元素,就是會強制換行的元素,比如。將元素推向左側。請根據不同的實際情況,選擇最合適的方式。再次重申一下,是為子元素創建定位環境。,由于浮動元素占據了一定的寬度,新創建的會因此而變窄。這里只是為了更好地去理解而做一個例子。
什么是 BFC
W3C 為瀏覽器規定了三種定位模型:Normal Flow, 浮動, 和絕對定位。本文所介紹的 BFC (Block Formatting Model) 是屬于 Normal Flow 中的一小節內容,并且這部分內容只有三段話。第一段:
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with "overflow" other than "visible" (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
簡單來說,BFC 僅僅是一種定位的情況,即當元素滿足 BFC 的條件時,瀏覽器怎么去顯示它。上面這短話講的是如何建立 BFC,只要滿足其中任何一個條件就可以了。可能需要解釋一句話,就是:block containers that are not block boxes。
block box 是指塊級元素,就是會強制換行的元素,比如 div。block container 是指可以包含塊級元素的元素,但它不一定要換行,比如 div, td。可以看到,后者的范圍更大一點,兩者異或的結果就是這句話的意思了。除了規范上列舉的 inline-block、table-cell 等,主流瀏覽器還支持 flex 。
建立 BFC默認的 div 是塊級元素,并不是 BFC,所以需要一些額外的樣式來生成。按照規范,我們大概有如下(不止)的手段,以及相應的代價:
disblay: table; 無法解決響應式的問題。
display: inline-block; 會使后續內聯元素顯示在同一行。
position: absolute; 將元素從 normal flow 中剝離出來。
float: left; 將元素推向左側。
overflow: scroll; 會出現滾動條。
overflow: hidden; 會截斷溢出的內容。
請根據不同的實際情況,選擇最合適的方式。
仔細想一下,在 normal flow 的章節中寫道,用 float: left; 或者 position: absolute; 去創建 BFC,是不是有點矛盾?不然。BFC 指的是為子元素創建一個定位環境,浮動和絕對定位是針對該元素本身,而不是其子元素。
外邊距合并在 normal flow 中,我們知道,垂直方向上相鄰元素的外邊距取兩者中較大的值,例子:
第一塊第二塊第三塊
相應的 CSS:
.container {margin:20px;border:1px solid #212121;width:300px;background-color:#009688;} .c1 {margin:10px 0;height:40px;background-color:#FFC107;}
結果示意圖:
可以看到,每個黃色塊之間的距離是 10px,而不是相加的 20px 。擴展一下,如果用 .c1 {margin:10px 0 15px;} 那么黃色塊之間的距離就是 15px,取較大值。如果是 .c1 {margin:10px 0 -15px;} 呢?是 10px,還是 0px,還是 -5px?
關于邊距合并,規范中是這么描述的:
Vertical margins between adjacent block-level boxes in a block formatting context collapse.
也就是說,邊距合并的條件是,子元素處于相同的 BFC 中,如果為其中一個子元素創建新的 BFC,就不會發生合并的情況了。
第三塊
現在為第三塊添加一個額外的父元素,并且為該元素創建 BFC:
.extra {overflow:hidden;}
圖不多帶帶給了,這里給個問題,就是,如果不添加父元素,直接把 .extra 類加給第三個塊,如下:
第一塊第二塊第三塊
可以防止邊距合并嗎?不行。再次重申一下,BFC 是為子元素創建定位環境。
BFC 的應用 清除浮動如果一個塊級元素的所有子元素都浮動了,那么它的高度就為 0 。
.c1 {float:left;margin:10px;width:100px;height:50px;background-color:#FFC107;}
對于同樣的 html,修改 .c1的樣式,添加浮動的效果,可以看到
父元素只剩下了邊框,并沒有 content height 。如果要清除浮動,可以為容器添加偽類:
.container:after{display:block;content:"";clear:both;}
這樣,父元素的高度就又回來了。
當然,我們也可以為父元素添加 overflow:hidden; 來清除浮動。
.container {overflow:hidden;}
這兩個方法都可行,前者很直白,clear:both; 本來就是用于清除浮動的,為什么用 overflow:hidden 也可以?因為這樣就創建了一個 BFC,對于子元素的排列,規范是這么寫的:
In a block formatting context, each box"s left outer edge touches the left edge of the containing block. This is true even in the presence of floats, unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).
子元素的外邊緣會觸碰到父元素的左側(嚴格來說是,子元素外邊距和父元素的內邊距)。如果父元素的高度為 0,那么就違背規范了。
所以為父元素添加浮動、絕對定位等任何用于創建 BFC 的方式,都可以清除浮動。
防止文字環繞常見的一種布局就是,特別是評論回復中,會看到在頭像右側有一段文字,就算文字很長,也不會出現在頭像下方,會一直保持在右側。
這樣的 HTML 格式很簡單:
...
.comment 中的內容省略不寫了。如果僅僅對 .avatar 左浮,就會出現文字環繞現象:
解決的辦法可以是為 .comment 添加一個適當的左外邊距,比如 90px 。
另一個辦法是利用 BFC 。
根據規范,子元素的外邊距必須向左靠著父元素的內邊距,也就是說,盡管 .avatar 浮動了,但是 .comment 還是會靠著父元素的左側內邊距,它們兩者是上下重疊的!
unless the box establishes a new block formatting context,這句話表明,只要為 .comment 創建 BFC,那么這個約束就可以被打破,即它們不會重疊。
in which case the box itself may become narrower due to the floats,由于浮動元素占據了一定的寬度,新創建的 BFC 會因此而變窄。
.avatar {width:70px;height:70px;float:left;margin:10px;background-color:#ffc107;} .comment {overflow:hidden;}多列布局
一般來說,如果要做寬度自適應的多列布局,就會用百分比做寬度單位,并且子元素浮動。那么問題就是,如果百分比換算到像素時,一旦子元素的寬度之和大于父元素,最后一列就會換行。
CSS3 本身可以實現多列布局,用 columns 屬性或者 flex 布局。這里只是為了更好地去理解 BFC 而做一個例子。
.column {float:left;margin:0 1%;width:31.33%;height:100px;background-color:#ffc107;}
先來算一下,左右邊距各 1%,寬度 31.33%,三列布局,總共 99.99%,應該不會超。但對于部分瀏覽器,寬度換算時是四舍五入的,比如,父元素的寬度為 500px,那么四舍五入,每列寬度為 157px,左右邊距 5px,總和 (157 + 5 2) 3 = 501,正好超 1px,最后一列換行。
最后一列要換行是因為浮動元素的特性,如果它不是浮動元素,那么就可以按照 normal flow 的規則來,即,向左靠至父元素左邊距。
然后,根據上個小節的知識,如果為元素創建新的 BFC,那么“向左靠”的規則可以打破。兩個條件結合,得到:
.column:last-child {float:none;overflow:hidden;}
雖然可以防止換行,但是最后一列的間距有點不一致。
本文主要是講了 BFC 的兩個關鍵點,第一:如何創建,以及每種方式的代價;第二:特性,防止默認的邊距合并和向左靠至父元素內側。很多衍生用法都是基于這兩種特性來的。
不過,往往我們是直接去記用 overflow:hidden; 可以清除浮動,并沒有想為什么,畢竟內容不多。有時候想想原理,也挺有意思的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/111151.html
摘要:官方說法就是它規定了用戶端在媒介中如何處理文檔樹。是的包含塊,同時又是的包含塊,不是絕對的。因此稱為匿名盒子。行內盒子行內級元素會生成行內級盒子,該盒子同時會參與行內格式化上下文的創建。如果只有一個值指定為,則其使用的值來自相等。 作者:陳大魚頭 github: KRISACHAN 盒模型 The CSS box model describes the rectangular b...
摘要:到底是何方神圣可以簡單看作是中的。和產生新的特性一樣,無法通過屬性直接設置,而是通過某些屬性間接開啟這一特性。不同的是某些屬性是以不可逆方式間接開啟為。因此所引發的問題,很大程度可以理解為在不應該的或沒有預料到的地方產生新的導致的。 前言 過去一直聽說舊版本IE下很多詭異bug均由一個神秘角色引起的,那就是hasLayout。趁著最近突然發神經打算好好學習CSS,順便解答多年來的疑惑。...
摘要:并且這種過程遵循標準的描述只要不是和絕對定位方式布局的,都在普通流里面。定位相對定位在普通流之中,是相對于它在普通流中的位置中進行移動,元素占據原來位置絕對定位脫離普通流,不占據空間相對于距離它最近的那個已定位的祖先相對絕對元素決定的。 視覺格式化模型 頁面(文檔樹)可以想象成是由一個個的Box組合而成的,而視覺格式化模型(Visual formatting model)是一套規則,將...
摘要:屬性語法層面僅對屬性作粗略分類。重點還是概念均決定了布局基礎模式。常規布局的重心與難點。對應標準第章布局上下文格式化上下文在常規流中的框,都屬于一個格式化的上下文中規則脫胎自文字排印,核心概念是。 發端自此。本文細節從略,只做主干梳理。 showImg(https://segmentfault.com/img/bVpFuh); 這個樹主要還是在借CSS2.1標準的骨架,填充進一些新的C...
閱讀 1354·2021-09-10 10:51
閱讀 2829·2019-08-30 15:54
閱讀 3367·2019-08-29 17:11
閱讀 926·2019-08-29 16:44
閱讀 1390·2019-08-29 13:47
閱讀 1086·2019-08-29 13:47
閱讀 1485·2019-08-29 12:23
閱讀 1038·2019-08-28 18:18