看了很多關於BFC的文章,就總結一下。終於應該算是明白了!css
其實要說BFC,就要說普通流(normal flow),就要說IFC(內聯格式化上下文),在一塊兒都說了,才能講的明白。html
普通流說白了就是怎樣把文檔中的元素等自上而下一個一個的呈現出來,這些元素怎麼在頁面中擺放,而這個呈現過程就是普通流node
那麼普通流是怎麼樣把頁面佈局呈現的呢?就是經過BFC和IFC,還有一個relative positioning(相對位移),今天重點講解BFC和IFCweb
BFC名字很高大上,說白了就是一個規則,這個規則應用於塊級元素(div,p)上。segmentfault
IFC這個規則應用於內聯元素(span,em,i)上。ide
在文檔呈現開始的時候,會自動建立一個BFC和IFC,來對整個頁面進行佈局,在沒有咱們經過設置一些屬性,來建立一個新的BFC的時候,整個文檔就這一個BFC和IFC,因此全部的元素都要使用這個規則。佈局
在普通流中,全部的盒子(不論是內聯盒子(內聯元素等)仍是塊級盒子(塊級元素等))都要屬於一個格式化上下文,不是屬於塊級格式化上下文就是屬於內聯格式化上下文,可是不能同時屬於二者,塊級元素佈局遵循塊級格式化上下文的規則,內聯元素佈局遵循內聯格式化上下文的規則來進行佈局.就是這兩個規則使得頁面的全部元素有序的佈局,才呈現出咱們所看到的web頁面。網站
什麼是BFC,IFCspa
BFC,IFC,就是控制元素如何進行佈局。code
BFC規則:
1.若是給一個元素建立了一個BFC,就至關於建立了一個新的容器,容器內和容器外中的元素不會相互影響。外邊的BFC規則,不會對容器裏的BFC產生影響,而容器裏面的BFC也不會對容器外的BFC產生影響,也就是相互隔絕,互不影響。
2.盒子的佈局開始是從包含容器的頂部開始的。
3.同一個BFC中,在兩個相鄰的塊級元素中,垂直margin會發生摺疊
4.每一個盒子的左邊界都要緊靠包含容器的左邊界(這也就解釋了爲何塊級元素都是單獨成一行的,若是不單獨成行,第二個盒子的左邊界怎麼緊靠包含容器的左邊界);
這第四個是最重要的佈局規則
IFC規則:
1.盒子是水平一個接一個的排列,水平的margin,內邊距,邊框是能夠有的。
2.垂直方向的對齊,多是底部對齊,頂部對齊,也多是基線對齊(這個是默認的);ps.這裏的盒子應該是指的內聯元素的盒子(span,strong等)和匿名內聯盒子(只有文本,沒有內聯元素包含,自動建立的),他們合稱內聯盒子,一個或者多個內聯盒子組成一個行框,行框的寬度由包含塊和出現的浮動決定的(爲何有浮動呢,後面解釋);行框的高度決定看個人這篇文章(css之line-height);必定要分清楚,行框和內聯盒子的關係,要否則我所說的你就不太可能理解
3.行框中的內聯盒子的高度小於行框的高度時,內聯盒子的垂直方向的對齊方式取決於vertical-align屬性
4.當一個行框水平不能容納內聯盒子時,他們將會在垂直方向上產生多個行框,他們上下一個挨着一個,可是不會重疊
5.通常來講,行框的左邊界緊挨着包含容器的左邊界,行框的右邊界緊挨着包含容器的右邊界,(是兩個邊都緊挨着)。然而,浮動盒子可能存在於包含邊框邊界和行框邊界之間(後面解釋這種狀況);
6.多個內聯盒子的寬度小於包含他們的行框時,他們在水平方向的分佈取決於text-align屬性(默認是left)
能產生新的BFC的屬性:
1.float的值不爲none。
2. overflow的值不爲visible。
3.display的值爲table-cell, table-caption, inline-block中的任何一個。
4.position的值不爲relative和static。
只要給元素設置這些屬性,則這些元素容器就不受外面的BFC約束了,他會給本身和他包含的元素應用新的BFC。也就是如今這些BFC分庭抗禮,你管不着我,我管不着你,只是咱們兩個的BFC規則是同樣的。
若是你上面這些沒有看懂的話,經過代碼必定能看懂。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test</title> <style> body,div{ margin:0; padding:0; } #box1,#box2,#box3{ width:100px; height:110px; border: 1px solid red; } #box4{ width:500px; border:1px solid red; height:100px; } #box4Child{ width:100px; height: 50px; border: 1px solid black; float:left; } </style> </head> <body> <div id="box1"></div> <div id="box2"></div> <div id="box3"> <span>我是內聯元素盒子</span>我是內聯匿名元素盒子<em>我也是內聯元素盒子</em> </div> <div id="box4"><div id="box4Child"></div><span>我是內聯元素盒子</span>我是內聯匿名元素盒子<em>我也是內聯元素盒子</em></div> </body> </html>
文檔解析我就從body開始提及,我就形象一點說,
1.當普通流碰見body元素時,一看你是塊級元素,應用BFC規則,因此,你要從你包含容器html元素頂部開始,左邊緊靠他的左邊,因而body就佈局好了
2.接下來就是body裏面的的box1了,普通流一看,你也是塊級元素,你也要應用BFC規則,由於你是第一個body的第一個元素,因此從body容器的頂部開始佈局,你的左邊也要緊靠body的左邊,而且你後面的元素要距離你10px,因而乎,box1就佈局好了
3.box2開始了,box2跟普通流說你看box1寬度才100px,你讓我在他後面吧,咱們兩個在一行才200px,普通流說不行,BFC的規則是你的左邊必須緊靠包含容器(body元素)的左邊,因而乎box2就只能本身一行了,(這也就是解釋了爲何塊級元素單獨成行),普通流說你看你的margin-top和box1的margin-bottom是相鄰的,根據BFC大家必須摺疊,因而他們兩個之間的距離就10px,而不是20px;
4.同理,box3跟相似上面的,因而box3就佈局好了;
5.如今進行box3的內部了,IFC說,span是內聯元素應該應用個人規則,我先建立一個行框(行框是他的左邊挨着包含框的左邊,右邊挨着包含框的右邊),這時發現一個行框過小,不能包含的了這個內聯盒子,因而,就在下面又建立了一個行框,來包含這個內聯盒子。此次兩個行框終於把span內聯盒子裝下了,接下來是又是一個盒子,此次是個匿名內聯盒子,既然都是內聯的,就挨着span內聯盒子繼續吧,發現也是放不下,就又建立了一個內聯盒子,下面的em也是那樣我就不說了,balabala。
6. 接下來開始佈局box4,一看是塊級元素就使用BFC。
7. 進行box4內部佈局,一看是塊級元素可是呢她又有float屬性,這是就建立一個新的BFC,這時就不受BFC規則的約束了。就不須要獨佔一行等規則了,可是呢,這又牽扯到float佈局定位機制,float的一些特性,float是這樣的,好比設置左浮動,那麼它的左邊必定要緊挨着包含元素的左邊或者是另外一個浮動元素的右邊。多了我就不說了,看官方文檔。這時box4child就佈局好了,接下來就佈局後面的東西了,一看是一個內聯元素,好吧,就建立一個行框,這時要注意了上面IFC規則的第五條的後半部分,也就是說,如今在這裏,這個行框的左邊界不在緊挨着包含塊的左邊界了他也是能夠挨着浮動元素的邊界的,因而就產生了圖中的效果,後面的東西同理上面就很少說了。
僅僅是我的理解,若有不對歡迎指正交流!
ps。以前寫了一個爬取指定網站的算是小爬蟲吧,使用nodejs寫的,裏面我添加了爬取博客園,csdn的關於web的版塊,segmentfault問答,segmentfault文章,百度貼吧的JavaScript吧,w3ctech,w3cfuns等,我也就常去這幾個網站了。界面我就以簡潔爲主。如今我就一直使用它來看文章,主要是簡單快捷方便;地址:小爬蟲