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