1. 為什么會有BFC和IFC
Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the 'display' property make an element block-level: 'block', 'list-item', and 'table'.
Block-level boxes are boxes that participate in a block formatting context.
2. 什么是BFC和IFC
-
BFC
1. 什么時候會產生BFC:
- float is not none
- position is absolute & fixed
- display is table-cell,table-caption,inline-block,flex,inline-flex
- overflow is not visible
- block-level box
2. 特性:
3. 作用:
此處闡述一下自己的理解:如果父元素只包含浮動元素,因為浮動元素是不包含在正常流的,浮動孩子將會脫離頁面的常規流,因此父元素相當於不包含任何元素,高度為0。
而BFC里面有兩條規則:
1、BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此。
2、計算BFC的高度時,浮動元素也參與計算
overflow:hidden會產生新的BFC,子元素的被包含在父元素的BFC中,因此父元素不受子元素影響,恢復常規布局,遵循BFC規則,同時計算高度時,父元素的高度會將浮動元素算進來,因此父元素有了高度。
不過這里要闡述一件事就是高度塌陷只出現在父元素包含且只包含浮動元素的時候:
看圖:在父元素沒有明確定義height的時候,如果只包含浮動元素,父元素會出現高度塌陷的問題。(其中的解決方法主要有添加偽元素clear:both,設置父元素height,設置父元素overflow:hidden等方式)


- IFC
在IFC中,內聯元素在水平方向上一個接一個的排布,其中,容器之間水平方向上的margin,padding,border方向上是好使的。他們垂直方向上有很多種對其方式,比如居底部或頂端對齊,或者基線對齊。他們對齊完了之后形成的這個四方塊兒區域,叫做一個line box(行框)。
一個line box的寬度由包含它的元素的寬度和包含它的元素里面有沒有float元素來決定,而高度由內部元素中實際高度最高的元素而計算出來。
line box的高度是足夠高來包含他內部的容器們的,也可能比它包含的容器們都高(比如在基線對齊的時候),當他包含的內部容器的高度小於line box的高度的時候,內部容器的垂直位置由自己的vertical這個屬性來確定。當內部的容器盒子太多了一個line box裝不下來,他們折行之后會變成兩個或者多個line box, line box們相互之間垂直方向不能分離,不能重疊。
一般來說,line box的左邊緣挨着包含它的元素的左邊緣,並且右邊緣挨着包含它的元素的右邊緣,浮動元素會在包含他們的元素的邊緣和line box的邊緣之間,所以雖然在同一個IFC下的line box們通常擁有相同的寬度(就是包含他們的容器的寬度),但是也會因為浮動元素的搗亂,導致line box們的可用寬度產生了變化不一樣了。在同一個Ifc下的line box們的高度也會不一樣(比如說,一個line box里有個比較大的image,他就高了)。
如果一個line box 里的內聯元素們的寬度總和小於這個line box的寬度,那么他們在這個line box里的水平方向的排布方式由 text-align這個屬性來決定,如果這個屬性被設置成了“justify”,可以使這些盒子在剩余空間內拉伸(除了inline-table 和 inline-block的元素)
在一個line box中,當他包含的內部容器的高度小於line box的高度的時候,內部容器的垂直位置由自己的vertical這個屬性來確定。那么,我們設想一下,如果手動創建一個IFC的環境,讓line box的高度是包含塊的高度的100%,讓line box內部的元素使用vertical-align:middle,就可以實現垂直居中。
一個line box的高度由內部元素中實際高度最高的元素而計算出來。所以,我們在line box中插入一個高度100%的inline-block元素。則會把整個line box撐高直到包含塊的100%.當內聯元素的寬度超過了line box的寬度,那么它會折行分裂成了幾個line box,如果這個元素里面的內容不可以折行,例如只有一個字,或者white-space設置了nowrap/pre。那么內聯元素會溢出line box。當一個內聯元素分裂時,分裂處的 margins, borders 和 padding不會有任何視覺效果(或者其他任何分裂,只要是有多個line box)。line box 的生存條件是在IFC中並且包含inline-level元素,如果line box里沒有文本,空白,換行符,內聯元素,也沒有其他的存在IFC環境中的元素,(如inline-block,inline- table,images等),將會被視為零高度,也將會被視為沒有意義。補充:在IFC的環境中,是不能存在block-level元素的,如果將block-level元素插入到IFC中,那么此IFC將會被破壞掉, 而block-level元素前的元素和block-level元素后的元素將會各自自動產生一個匿名容器其包圍,這個匿名的容器內部環境將是一個新的 IFC。
此處補充一些自己對於IFC高度計算的理解:主要是line-height和height
IFC中height的計算方式:line height表示高度
*line-height如果沒有顯式聲明,那么繼承父元素的line-height;如果顯示聲明了,則用聲明后的高度(vertical-align的時候參考的邊界值)
css中的line-height表示line space(行間差值) + font-size

可以得到:1.height對inline元素並不起作用 2.只有設置了line-height的inline元素才會參與vertical-align的排列規則(這里個人分析是因為只有設置了高度,vertical-align時才能計算到邊界值,從而對其進行排列,否則默認都是baseline規則)
此處可以再看一個例子: