BFC 佈局規則
什麼是 BFC
既 Block Formatting Context(塊級格式化上下文),是一個獨立的渲染區域,讓處於 BFC 內部的元素與外部的元素相互隔離,使內外元素的定位不會相互影響。html
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.前端
浮動元素和絕對定位元素,非塊級盒子的塊級容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不爲「visiable」的塊級盒子,都會爲他們的內容建立新的BFC(塊級格式上下文)。git
—— W3Cgithub
即,存在如下幾種方案可建立 BFC:面試
- 浮動元素,
float
值不爲none
- 絕對定位元素,
position
屬性爲absolute
,fixed
- 非塊級盒子的塊級容器(
display
值爲inline-blocks
,table-cells
,table-captions
等) overflow
的值不爲visible
(visiable
是默認值。內容不會被修剪,會呈如今元素框以外)- 除此以外,根元素, HTML 元素自己就是 BFC( 最大的一個BFC )
BFC佈局規則
- 內部的盒子會在垂直方向,一個一個地放置;
- 盒子垂直方向的距離由
margin
決定,屬於同一個 BFC 的兩個相鄰 Box 的上下margin
會發生重疊; - 每一個元素的左邊,與包含的盒子的左邊相接觸,即便存在浮動也是如此;
- BFC 的區域不會與
float
重疊; - BFC 就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素,反之也是如此;
- 計算 BFC 的高度時,浮動元素也參與計算。
BFC 做用
自適應兩欄佈局
阻止元素被浮動的元素覆蓋,自適應成兩欄佈局算法
<!-- 左邊的寬度固定,右邊的內容自適應寬度(不設置寬度) --> <div class="ldiv"> 左浮動的元素 </div> <div class="rdiv"> 沒有設置浮動, 沒有設置寬度 width 可是觸發 BFC 元素 </div> <style> .ldiv { height: 100px; width: 100px; float: left; background: aqua; } .rdiv { height: 100px; background: blueviolet; overflow: hidden; } </style>
清除內部浮動
解決浮動元素不佔高度的問題(浮動元素未被包裹在父容器)chrome
<div class="parent"> <div class="child"></div> </div> <style> .parent { border: 1px solid blueviolet; overflow: hidden; } .child { width: 100px; height: 100px; background: aqua; float: left; } </style>
解決 margin 重疊
爲了防止 margin 重疊, 可使多個 box 分屬於不一樣的 BFC 時ide
<div class="container"> <p></p> </div> <div class="container"> <p></p> </div> <style> .container { overflow: hidden; } p { width: 100px; height: 100px; background: aqua; margin: 10px; } </style>
阻止元素被浮動元素覆蓋
<div class="ldiv"> 左浮動的元素 </div> <div class="rdiv"> 沒有設置浮動, 可是觸發 BFC 元素 </div> <style> .ldiv { height: 100px; width: 100px; float: left; background: aqua; } .rdiv { width: 300px; height: 200px; background: blueviolet; overflow: hidden; } </style>
CSS 格式化上下文
Formatting context(格式化上下文) 是 W3C CSS2.1 規範中的一個概念。它是頁面中的一塊渲染區域,而且有一套渲染規則,它決定了其子元素將如何定位,以及和其餘元素的關係和相互做用。佈局
在 CSS 中除了 BFC (塊級格式化上下文),還有 IFC、GFC、FFC等,這些統稱爲CSS 格式化上下文 ,也被稱做 視覺格式化模型 。而 CSS 視覺格式化模型是用來處理文檔並將它顯示在視覺媒體上的機制。學習
簡單地說, CSS 格式化上下文 就是用來控制盒子的位置,即實現頁面的佈局 。
IFC:行內格式上下文
行內格式化上下文(Inline Formatting Context),簡稱 IFC 。主要用來規則行內級盒子的格式化規則。
IFC 的line box(線框)高度由其包含行內元素中最高的實際高度計算而來(不受到豎直方向的padding/margin影響)
IFC 的行盒的高度是根據包含行內元素中最高的實際高度計算而來。主要會涉及到CSS中的 font-size
、 line-height
、 vertical-align
和 text-align
等屬性。
行內元素從包含塊頂端水平方向上逐一排列,水平方向上的 margin
、 border
、 padding
生效。行內元素在垂直方向上可按照頂部、底部或基線對齊。
當幾個行內元素不能在一個單獨的行盒中水平放置時,他們會被分配給兩個或更多的(Vertically-stacked Line Box)垂直棧上的行盒,所以,一個段落是不少行盒的垂直棧。這些行盒不會在垂直方向上被分離(除非在其餘地方有特殊規定),而且他們也不重疊。
那麼IFC通常有什麼用呢?
- 垂直方向上,當行內元素的高度比行盒要低,那麼
vertical-align
屬性決定垂直方向上的對齊方式。 - 水平方向上,當行內元素的總寬度比行盒要小,那麼行內元素在水平方向上的分部由
text-align
決定。 - 水平方向上,當行內元素的總寬度超過了行盒,那麼行內元素會被分配到多個行盒中去,若是設置了不可折行等屬性,那麼行內元素會溢出行盒。
- 行盒的左右兩邊都會觸碰到包含塊,而
ef="https://github.com/sisterAn/blog">float 元素則會被放置在行盒和包含快邊緣的中間位置。
GFC(GrideLayout formatting contexts):網格佈局格式化上下文
Grid 格式化上下文(Grid Formaatting Context),俗稱 GFC 。和FFC有點相似,元素的 display
值爲 grid
或 inline-grid
時,將會建立一個Grid容器。該完徹底全器爲其內容建立一個新的格式化上下文,即Grid格式化上下文。這和建立BFC是同樣的,只是使用了網格佈局而不是塊佈局。
那麼GFC有什麼用呢,和table又有什麼區別呢?首先一樣是一個二維的表格,但GridLayout會有更加豐富的屬性來控制行列,控制對齊以及更爲精細的渲染語義和控制。
FFC(Flex formatting contexts):自適應格式上下文
Flex格式化上下文(Flexbox Formatting Context)俗稱 FFC 。當 display
取值爲 flex
或 inline-flex
,將會建立一個Flexbox容器。該容器爲其內容建立一個新的格式化上下文,即Flex格式化上下文。
惋惜這個牛逼的屬性只有谷歌和火狐支持,不過在移動端也足夠了,至少safari和chrome仍是OK的,畢竟這倆在移動端纔是王道。
不過要注意的是,Flexbox容器不是塊容器(塊級盒子),下列適用於塊佈局的屬性並不適用於Flexbox佈局:
- 多列中的
column-*
屬性不適用於Flexbox容器 float
和clear
屬性做用於Flex項目上將無效,也不會把讓Flex項目脫離文檔流vertical-algin
屬性做用於Flex項目上將無效::first-line
和::first-letter
僞元素不適用於Flexbox容器,並且Flexbox容器不爲他們的祖先提供第一個格式化的行或第一個字母