摘要:它是用于決定盒子的布局及浮動相互影響范圍的一個區(qū)域。小白反思如果世界的運行都有自我運行的一套機制,那么的世界必然有自己的一套規(guī)則。外邊距合并當時在回答外邊距的問題時,總結(jié)出了合并的一條規(guī)則必須相鄰。
最初的夢
了解BFC后,能夠更深入的明白外邊距合并原理。
了解BFC后,能夠更深入的明白浮動的行為。
了解BFC后,知識就是你的,總不會吃虧對吧?哈哈
之前有兩篇文章《行內(nèi)元素的一些探索》、《浮動的一些探索》,或多或少隱式的牽連到了塊級格式化上下文。
今天正式介紹BFC,以加深對CSS的理解。
-------------寫在前面---------------
BFC是時候表演真正的技術(shù)了之前的內(nèi)容是參考MDN的塊級格式化上下文和自我思考的過程組成,今日重讀感覺糟糕之極,于是便在此給出w3c規(guī)范中的定義以作補充。
W3C規(guī)范中是這樣定義BFC的:
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.
這里需要注意的幾個點block containers、block boxes、their contents。
浮動、絕對定位元素,非塊級盒子的塊級容器(比如display屬性值為inline-block,tale-cells和table-captions的元素),以及overflow屬性設(shè)置為visible以外的塊級盒子都為它們的內(nèi)容創(chuàng)建了新的塊級格式化上下文。
原文在這
block formatting context
徹底了解w3c規(guī)范BFC的定義后可以直接閱讀最后一部分內(nèi)容(bfc是時候表演技術(shù))
BFC的生理構(gòu)造 BFC外衣小白反思塊級格式化上下文(block formatting context)是頁面CSS視覺渲染的一部分。它是用于決定盒子的布局及浮動相互影響范圍的一個區(qū)域。BFC之間不會相互影響。
一共三句話。
第一句話忽略不計。
第二句話很關(guān)鍵。不過先反問下,這句話里的盒子指的是誰,也就是說決定誰的浮動和布局?
這個問題的答案其實很簡單,這里的盒子指代的是產(chǎn)生BFC元素的塊級子元素。
反思:什么條件產(chǎn)生BFC,決定誰的布局?
解答:BFC的產(chǎn)生見下文。塊級格式化上下文(BFC)從字面上理解應(yīng)該能推測出盒子指代的是塊級子元素。
第三句話也很重要。BFC之間不會相互影響,那么BFC和其它的元素會發(fā)生影響,BFC中的元素和其它的元素會發(fā)生影響嘛?
答案是肯定的,BFC和其它元素會發(fā)生影響,但BFC中的元素不會受其它元素影響。
反思:這里的其它元素指的是什么元素?
解答:處在同一個包含塊中同級別(互為兄弟關(guān)系)的元素。
官方外衣總是華麗,值得琢磨,盡管仔細思考了也必然有所獲。但,作為程序員,怎能不去了解她的心。
小白反思塊級格式化上下文包括了創(chuàng)建該上下文的元素的所有子元素,但不包括創(chuàng)建了新的塊格式化上下文的子元素。
如果世界的運行都有自我運行的一套機制,那么BFC的世界必然有自己的一套規(guī)則。世界的運行總避免不了能力超凡者打破規(guī)矩、突破限制形成另一個世界并不再受之前的約束。這里的能力超凡者就可以理解為創(chuàng)建了新的塊級格式化上下文的元素。那么如果獲得創(chuàng)造新世界的能力呢?
BFC,你是怎么來到這個世界的?世界從來都不是平等的,或許就像海賊王里的天龍人,高高在上。BFC有些元素與生俱來,有些就靠開發(fā)者來賦予。
根元素或其它包含它的元素
浮動和定位元素(設(shè)置了float不為none或position不為relative和static)
overflow不為visible的元素
display設(shè)為inline-block、table-cell和table-caption
新的世界,總會形成一套自己的規(guī)矩。
BFC的游戲規(guī)則在BFC中,盒子從頂端開始垂直地一個接一個排列,兩個盒子之間的垂直間隙是由他們的margin值決定
在同一個BFC中,兩個相鄰塊級盒子的垂直外邊距會產(chǎn)生重疊
在BFC中,每一個盒子的左邊緣都會觸碰到容器到左邊緣
計算BFC元素高度時,浮動元素也參與計算
BFC是時候表演真正的技術(shù)了 文字環(huán)繞這是一種常見的現(xiàn)象。有些時候,實際需要的效果是下面這樣的。
為了直觀的看到BFC的作用,給段落p添加個背景色。
清晰看見p的行框有一部分是在綠色透明塊之下的,現(xiàn)在賦予p元素BFC的話,那么浮動的Div和p就相當于超強者(各自形成自己的BFC),根據(jù)BFC之間互不影響這一特性。效果就是下面這樣的。
當時在回答div外邊距的問題時,總結(jié)出了合并的一條規(guī)則:margin必須相鄰。但當時只探究了margin合并的條件,卻未曾探究條件的產(chǎn)生(什么情況才算相鄰)?,F(xiàn)在從BFC的角度重聊這個話題。
margin相鄰的前提條件
必須處于文檔正常流的塊級盒子,并且處于同一個BFC
沒有線盒,沒有清除區(qū)域(clearance),沒有padding和border
margin都是垂直方向上的
針對第一點,進行一個簡單的說明。
這是常見的外邊距合并。觸發(fā)合并的因素符合相鄰的前提條件。
代碼如下
一般情況阻止外邊距重疊會給父元素Div.parent設(shè)置overflow:hidden。
那么如果給Div.child設(shè)置overflow:hidden呢?
.child{width:200px;height:200px;margin:30px 0;background:#f3a;overflow:hidden;}
怎么會這樣?Div.child不是產(chǎn)生了新的BFC嗎?那么Div.parent和Div.child就不在同一BFC中了。那么不是違背了margin相鄰的前提條件中的第一條了嗎?為什么還發(fā)生重疊了?
反思:重疊既然發(fā)生了,說明一個問題,那就是margin相鄰的條件全部滿足了。這說明Div.parent和Div.child處在同一個BFC,overflow:hidden設(shè)置給父元素時確實發(fā)生作用并產(chǎn)生了新的BFC,并阻止重疊。
overflow:hidden設(shè)置給子元素時也確實作用并產(chǎn)生新BFC,但卻沒阻止重疊。
說到這,需要考慮的問題就是BFC概念了。
在BFC的心這一節(jié)里有提BFC的內(nèi)部組成。這里再次引用:
塊級格式化上下文包括了創(chuàng)建該上下文的元素的所有子元素,但不包括創(chuàng)建了新的塊格式化上下文的子元素。
一句話概括:BFC是為其內(nèi)容而生的。
BFC不包括產(chǎn)生BFC的元素,也就是不包括生產(chǎn)者!
overflow:hidden設(shè)置給父元素時,阻斷了重疊發(fā)生。這說明Div.parent和Div.child不處在同一個BFC中。child處在parent產(chǎn)生的BFC中,而parent處在最開始的BFC中。所以重疊不發(fā)生。
overflow:hidden設(shè)置給子元素時,重疊發(fā)生。這說明Div.parent和Div.child處在同一個BFC中。child產(chǎn)生的BFC并不會把child自己也納入進去,而是作用于child的子元素。因此parent和child依然處于同一個BFC中,所以重疊發(fā)生。
小白提問
考慮下Div.parent和Div.child多帶帶設(shè)置display:inline-block時,會發(fā)生什么現(xiàn)象?
答案或許是這樣的,和overflow一樣唄。
實踐才出真理。
無論是給父元素還是子元素設(shè)置display:inline-block,重疊都不會發(fā)生。為什么呢?不都是產(chǎn)生了BFC嗎?
小白揭秘
margin相鄰前提條件的第一條里是要求必須是塊級盒子,而在w3c規(guī)范中規(guī)定,塊級盒子的display屬性必須是以下三種之一:"block", "list-item", 和 "table"。display:inline-block不在其列,因而無論給誰設(shè)置display都不滿足條件。所以重疊不發(fā)生。
下面代碼中的margin-top方向為什么沒有產(chǎn)生下移的視覺效果,而margin-left方向居然產(chǎn)生了左移的效果。
這個問題困惑了我很久。淺談個人對該問題的理解:
在閱讀前,最好深入margin屬性。如果不愿意看的話,那就直接看下面這段話吧。
在 margin 中 top、right、bottom、left 的參考線并不一致為一類,而是分為了兩類參考線。top 和 left 的參考線屬于一類,right 和bottom 的參考線屬于另一類。top 以 containing block 的 content 上邊或者垂直上方相連元素 margin 的下邊為參考線垂直向下位移;left 以 containing block 的 content 左邊或者水平左方相連元素 margin 的右邊為參考線水平向右位移。right 以元素本身的 border 右邊為參考線水平向右位移;bottom 以元素本身的border 下邊為參考線垂直向下位移。
小白分析
這段話首先將trbl分成了兩類。
其中top和left的參考線又分為兩種。
container block content top(left)
top和left分別對應(yīng)父元素的content top edge或content left edge
sibling margin-bottom (margin-right)
top和left分別對應(yīng)相鄰元素的margin-bottom或margin-right(這里當然會發(fā)生margin collapse)
bottom和right是以元素自身的border-bottom(border-right)為邊界。
問題剖析
1.margin-left發(fā)生了水平偏移,且child在水平方向并沒有相鄰元素,這說明其參考是父元素(section)的content left edge。
2.margin-top沒發(fā)生偏移,這至少說明其參考線不是父元素(section)的content top edge。然而在垂直方向上,child是擁有一個相鄰的東西(clearance),那么很明顯就是clearance搗鬼。如果clearance被解析成盒模型了,那么垂直方向肯定能產(chǎn)生位移,如果解析成其他一些東西了,那么沒有位移就很正常了。 (這一點也模糊,希望有人指點)
w3c clearance
兩列布局,我來講點不一樣的兩列布局的要求:
一欄寬度固定一欄寬度隨瀏覽器發(fā)生改變
以下最常見的代碼,沒有任何問題。
This is main content
換個思路實現(xiàn)兩列布局,各位看官看好嘍。
This is main content
這里做了三處修改
將main與aside的位置交換
為main添加右浮動,改變aside浮動方向,并顯式設(shè)置了width:100%
為main添加了margin-left:-200px;
這樣看上去是沒有任何一點問題的。
如果向main里添加更多的文字會發(fā)生什么?
那么第一種兩列布局會不會發(fā)生上面這種情況呢?
你真的懂BFC了嗎?
小白解析
第一種布局之所以不會發(fā)生重疊,是因為它們在同一個BFC中
第二種布局之所以會重疊,是因為它們在不同BFC中
圣杯、雙飛翼,我也來玩問題產(chǎn)生
I am boss
基本描述:此時給中間綠色塊div填寫內(nèi)容會出現(xiàn)重疊現(xiàn)象,原理同上述兩列布局
為了解決這個問題,出現(xiàn)兩種思路(或許雙飛翼是圣杯的優(yōu)化方案)
圣杯好像很好吃的樣子~
I am boss
以上就是圣杯布局。分析就不寫了。直接看雙飛翼布局吧,非常精妙的布局。
I am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am boss
小白分析
首先在不考慮使用position:relative的情況下,要達到圣杯布局的效果,那只能通過margin來作用。先貼張問題圖方便閱讀
那么直接給main(綠色的div)添加margin: 0 100px 0 250px;不就行了嗎?
由上述兩張圖可知道m(xù)argin屬性只有左邊的發(fā)生作用了,而右邊的未發(fā)生作用。這是因為屬性過分受限(overconstrained),將margin-right強制設(shè)為auto了。(調(diào)試器看不出來的)
因此該思路不可行。
于是便思索通過水平格式化這一idea來實現(xiàn)。
給main套一層div.wrap-main
將main的部分屬性(float、width)移到div.wrap-main,并為main添加margin: 0 100px 0 250px;
至此,雙飛翼布局已經(jīng)實現(xiàn)。
涉及知識點總結(jié):
水平格式化
屬性過分受限(overconstrained)
margin屬性深入了解
bfc的深入認識
float的深入了解
最后一點小收獲:
這張圖應(yīng)該很有印象吧,前面有喲。
為什么這里有個空白?aside.right在哪里呢?
盡管main的margin-right水平受限被設(shè)置為auto,但在計算和渲染時,100px仍然會發(fā)生作用。所以aside.left的margin-left:-100%不是靠著最左邊而是間隔了100px。受其影響,aside.right的margin-left:-100px就把自己藏在了最左邊(下圖的位置)。
以上純屬個人理解
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/115021.html
摘要:一個元素如果設(shè)置了但沒有設(shè)置此元素的位置在哪在涉及到絕對定位元素的位置問題時一個重要的概念是想要了解元素的位置還得找到此元素的才行如下是我進行的一系列測試以及對測試結(jié)果的試探性解釋文中的英文術(shù)語都不翻譯方便直接查或者其他技術(shù)文檔請持有懷疑精 一個元素如果設(shè)置了position: absolute;, 但沒有設(shè)置top, right, bottom, left, 此元素的位置在哪? 在涉...
摘要:后來居上當元素的層疊水平一致層疊順序相同的時候,在流中處于后面的元素會覆蓋前面的元素。相關(guān)連接深入理解中的層疊上下文和層疊順序?qū)盈B順序探究分層的顯示 什么是層疊上下文(stacking context) 可以理解為一個dom節(jié)點在Z軸高人一等,特性類似于BFC,即層疊上下文的內(nèi)部子元素再怎么翻江倒海,翻云覆雨都不會影響外部的元素。 CSS2創(chuàng)建層疊上下文的兩種方法(參考MDN) 根元...
摘要:布局中有一些概念,一旦你理解了它們,就能真正提高你的布局能力。我們通常有兩種方法來解決這個布局問題。是布局中的一個迷你布局你可以將看作是頁面內(nèi)的一個迷你布局。理解瀏覽器如何布置網(wǎng)頁是非?;A(chǔ)的。 CSS布局中有一些概念,一旦你理解了它們,就能真正提高你的 CSS 布局能力。本文是關(guān)于塊格式化上下文(BFC)的。你可能從未聽說過這個術(shù)語,但是如果你曾經(jīng)用CSS做過布局,你可能知道它是什么...
摘要:而就潛藏在其中,當你修改樣式時,一不小心就能觸發(fā)它而毫無察覺,因此沒有意識到的神奇之處。實例解決侵占浮動元素的問題我們知道浮動元素會脫離文檔流,然后浮蓋在文檔流元素上。 在寫樣式時,往往是添加了一個樣式,又或者是修改了某個屬性,就達到了我們的預(yù)期。而BFC就潛藏在其中,當你修改樣式時,一不小心就能觸發(fā)它而毫無察覺,因此沒有意識到BFC的神奇之處。 一、什么是BFC(Block Form...
閱讀 726·2021-10-14 09:42
閱讀 1980·2021-09-22 15:04
閱讀 1588·2019-08-30 12:44
閱讀 2147·2019-08-29 13:29
閱讀 2741·2019-08-29 12:51
閱讀 558·2019-08-26 18:18
閱讀 709·2019-08-26 13:43
閱讀 2822·2019-08-26 13:38