在普通流中,元素按照其在 HTML 中的前後位置至上而下佈局,在這個過程當中,行內元素水平排列,直到當行被佔滿而後換行,塊級元素則會被渲染爲完整的一個新行,除非另外指定,不然全部元素默認都是普通流定位,也能夠說,普通流中元素的位置由該元素在 HTML 文檔中的位置決定。css
在浮動佈局中,元素首先按照普通流的位置出現,而後根據浮動的方向儘量的向左邊或右邊偏移,其效果與印刷排版中的文本環繞類似html
在絕對定位佈局中(position值爲absolute或fixed),元素會總體脫離普通流,所以絕對定位元素不會對其兄弟元素形成影響,而元素具體的位置由絕對定位的座標決定。git
Formatting context(格式化上下文) 是 W3C CSS2.1 規範中的一個概念。它是頁面中的一塊渲染區域,而且有一套渲染規則,它決定了其子元素將如何定位,以及和其餘元素的關係和相互做用。github
格式化上下文有如下幾種類型:segmentfault
一個頁面是由不少個Box
組成的,元素的類型和display
屬性決定了這個Box
的類型。不一樣類型的 Box,會參與不一樣的 Formatting Context。Block level
的box會參與造成BFC,好比display
值爲block,list-item,table
的元素。Inline level
的box會參與造成IFC,好比display
值爲inline,inline-table,inline-block
的元素。ide
塊格式化上下文(Block Formatting Context,BFC) 是Web頁面的可視化CSS渲染的一部分,是塊盒子的佈局過程發生的區域,也是浮動元素與其餘元素交互的區域。(我的理解:BFC佈局方式和上述普通流佈局方式類似)佈局
具備 BFC 特性的元素能夠看做是隔離了的獨立容器,容器裏面的元素不會在佈局上影響到外面的元素,而且 BFC 具備普通容器所沒有的一些特性。flex
下列方式會建立塊級格式化上下文:ui
<html>
)float
不是 none
)position
爲 absolute
或 fixed
)display
爲 inline-block
)display
爲 table-cell
,HTML表格單元格默認爲該值)display
爲 table-caption
,HTML表格標題默認爲該值)display
爲 table、
`table-row、
table-row-group、table-header-group、
table-footer-group(分別是HTML table、row、tbody、thead、tfoot的默認屬性)或
inline-table`)overflow
值不爲 visible
的塊元素display
值爲 flow-root 的元素contain
值爲 layout
、content
或paint 的元素display
爲 flex
或 inline-flex
元素的直接子元素)display
爲 grid
或 inline-grid
元素的直接子元素)column-count
或 column-width
不爲 auto,包括
`column-count 爲
1`)column-span
爲 all
的元素始終會建立一個新的BFC,即便該元素沒有包裹在一個多列容器中(標準變動,Chrome bug)。塊格式化上下文包含建立它的元素內部的全部內容.spa
margin
決定。屬於同一個BFC的兩個相鄰Box的margin
會發生重疊margin-left
), 與包含塊的左邊(contain box left
)相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此。除非這個元素本身造成了一個新的BFC。float box
重疊。浮動的元素會脫離普通文檔流
<div style="border: 1px solid #000;"> <div style="width: 100px;height: 100px;background: #eee;float: left;"></div> </div>
因爲容器內元素浮動,脫離了文檔流,因此容器只剩下 2px 的邊距高度。若是使觸發容器的 BFC,那麼容器將會包裹着浮動元素。
效果如圖:
先來看一個文字環繞效果:
<div style="height: 100px;width: 100px;float: left;background: lightblue">我是一個左浮動的元素</div> <div style="width: 200px; height: 200px;background: #eee">我是一個沒有設置浮動, 也沒有觸發 BFC 元素, width: 200px; height:200px; background: #eee;</div>
這時候其實第二個元素有部分被浮動元素所覆蓋,(可是文本信息不會被浮動元素所覆蓋) 若是想避免元素被覆蓋,可觸第二個元素的 BFC 特性,在第二個元素中加入overflow: hidden,就會變成:
這個方法能夠用來實現兩列自適應佈局,效果不錯,這時候左邊的寬度固定,右邊的內容自適應寬度(去掉上面右邊內容的寬度)。
<head> div{ width: 100px; height: 100px; background: lightblue; margin: 100px; } </head> <body> <div></div> <div></div> </body>
從效果上看,由於兩個 div 元素都處於同一個 BFC 容器下 (這裏指 body 元素) 因此第一個 div 的下邊距和第二個 div 的上邊距發生了重疊,因此兩個盒子之間距離只有 100px,而不是 200px。
首先這不是 CSS 的 bug,咱們能夠理解爲一種規範,若是想要避免外邊距的重疊,能夠將其放在不一樣的 BFC 容器中。
<div class="container"> <p></p> </div> <div class="container"> <p></p> </div>
.container { overflow: hidden; } p { width: 100px; height: 100px; background: lightblue; margin: 100px; }
這時候,兩個盒子邊距就變成了 200px
<style> .box{ width:100px; height:100px; background:#ccc; } .wrap { background:yellow; } .wrap h1{ background:pink; margin:40px; } </style> <body> <div class="box">box</div> <div class="wrap"> <h1>h1</h1> </div> </body>
上圖wrap元素與h1元素之間l理論上本該有個40px的上下margin值,然而實際上父子元素並無存在margin值,與此同時,兩個div元素的間距爲40px。遇到這種情形,咱們如何處理?
處理方法其實有不少,在wrap元素中添加:overflow:hidden;或者overflow:auto;使其父元素造成一個BFC;也能夠在wrap元素中添加border:1px solid;或是padding:1px;這些均可以有效解決父子元素margin重疊問題。
IFC(Inline Formatting Contexts)直譯爲"內聯格式化上下文",IFC的line box(線框)高度由其包含行內元素中最高的實際高度計算而來(不受到豎直方向的padding/margin影響)。
IFC中框模型不徹底適用於參與內聯格式上下文的項。在水平書寫模式行中,水平填充、邊框和邊距將應用於元素,並左右推送文本。可是,不會應用元素上下的邊距。將應用垂直填充和邊框,但可能會在內容的上方和下方重疊,由於在內聯格式上下文中,填充和邊框不會將行框推開。
在行內格式化上下文中,框(boxes)一個接一個地水平排列,起點是包含塊的頂部。水平方向上的margin
,border
和padding
在框之間獲得保留。框在垂直方向上能夠以不一樣的方式對齊:它們的頂部或底部對齊,或根據其中文字的基線對齊。包含那些框的長方形區域,會造成一行,叫作行框。
當一個塊要在環境中水平居中時,設置其爲inline-block則會在外層產生IFC,經過text-align則可使其水平居中。
建立一個IFC,用其中一個元素撐開父元素的高度,而後設置其vertical-align:middle,其餘行內元素則能夠在此父元素下垂直居中。
GFC(GridLayout Formatting Contexts)直譯爲"網格佈局格式化上下文",當爲一個元素設置display值爲grid的時候,此元素將會得到一個獨立的渲染區域,咱們能夠經過在網格容器(grid container)上定義網格定義行(grid definition rows)和網格定義列(grid definition columns)屬性各在網格項目(grid item)上定義網格行(grid row)和網格列(grid columns)爲每個網格項目(grid item)定義位置和空間。
GFC將改變傳統的佈局模式,他將讓佈局從一維佈局變成了二維佈局。簡單的說,有了GFC以後,佈局再也不侷限於單個維度了。這個時候你要實現相似九宮格,拼圖之類的佈局效果顯得格外的容易。
FFC(Flex Formatting Contexts)直譯爲"自適應格式化上下文",display值爲flex或者inline-flex的元素將會生成自適應容器(flex container)。
Flex Box 由伸縮容器和伸縮項目組成。經過設置元素的 display 屬性爲 flex 或 inline-flex 能夠獲得一個伸縮容器。設置爲 flex 的容器被渲染爲一個塊級元素,而設置爲 inline-flex 的容器則渲染爲一個行內元素。
伸縮容器中的每個子元素都是一個伸縮項目。伸縮項目能夠是任意數量的。伸縮容器外和伸縮項目內的一切元素都不受影響。簡單地說,Flexbox 定義了伸縮容器內伸縮項目該如何佈局。
總體來講,FFC與BFC有點兒相似,但仍有如下幾點區別:
https://developer.mozilla.org...
https://developer.mozilla.org...
https://segmentfault.com/a/11...
https://zhuanlan.zhihu.com/p/...