BFC、IFC、GFC 和 FFC
前言
想要了解BFC、IFC、GFC、FFC,就必须先要了解FC。
FC的全称是:Formatting Contexts(格式化上下文),它是W3C规范中的一个概念。简单来说,它是页面中的一块渲染区域,并且有自己的一套渲染规则,它决定了其子元素如何定位,以及和其他元素的关系和相互作用。需要注意的是,它并不会影响区域外的元素
前置概念
先让我们了解几个基本概念
1、Box
简单来说,我们的web页面是由一个个Box组合而成的,而display等属性决定了Box的类型
1)block-level Box
当元素的 CSS 属性 display
为 block
, list-item
或table
时,它是块级元素 block-level
。块级元素(比如<p>
)视觉上呈现为块,竖直排列。 每个块级元素至少生成一个块级盒(block-level Box)
参与 BFC ,称为主要块级盒(principal block-level box)
。一些元素,比如<li>
,生成额外的盒来放置项目符号,不过多数元素只生成一个主要块级盒。
2)Inline-level Box
当元素的 CSS 属性 display
的计算值为inline
,inline-block
或inline-table
时,称它为行内级元素。视觉上它将内容与其它行内级元素排列为多行。典型的如段落内容,有文本或图片,都是行内级元素。行内级元素生成行内级盒(inline-level boxes),参与行内格式化上下文 IFC 。
3)flex container
当元素的 CSS 属性 display
的计算值为 flex
或 inline-flex
,称它为弹性容器。display:flex
这个值会导致一个元素生成一个块级(block-level)
弹性容器框。display:inline-flex
这个值会导致一个元素生成一个行内级(inline-level)
弹性容器框。
4)grid container*
**当元素的 CSS 属性 display
的计算值为 grid
或inline-grid
,称它为*栅格容器。
2、块容器盒(block container box)
只包含其它块级盒,或生成一个行内格式化上下文(inline formatting context)
,只包含行内盒的叫做块容器盒子。
也就是说,块容器盒要么只包含行内级盒,要么只包含块级盒。
块级盒
(block-level Box)
是描述元素跟它的父元素与兄弟元素之间的表现。块容器盒
(block container box)
描述元素跟它的后代之间的影响。
3、块盒(BLock Boxes)
同时是块容器盒的块级盒称为块盒(block boxes)
4、行盒(Line boxes)
行盒由行内格式化上下文(inline formatting context)
产生的盒,用于表示一行。在块盒里面,行盒从块盒一边排版到另一边。 当有浮动时, 行盒从左浮动的最右边排版到右浮动的最左边。
OK,了解完上面这些概念,我们再来看我们本篇文章的重点内容(终于要揭开各种FC
的庐山真面目了,期待~)
BFC(Block Formatting Contexts)块级格式化上下文
在MDN上是这样解释的,块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
1、如何创建BFC:
- 根元素(
<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
计算值(Computed)不为visible
的块元素display
值为flow-root
的元素contain
值为layout
、content
或 paint 的元素- 弹性元素(
display
为flex
或inline-flex
元素的直接子元素) - 网格元素(
display
为grid
或inline-grid
元素的直接子元素) - 多列容器(元素的
column-count
或column-width
(en-US) 不为auto,包括 ``column-count
为1
) column-span
为all
的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。
2、BFC的规则
- 内部的Box会在垂直方向,一个接一个地放置。
- Box垂直方向的距离由
margin
决定。属于同一个BFC的两个相邻Box的margin
会发生重叠。 - 每个元素的
margin box
的左边, 与包含块border box
的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。 - BFC的区域不会与
float box
重叠。 - BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算。
3、BFC的应用场景
1)解决块级元素垂直方向margin重叠
原因:外边距合并,当2个垂直外边距相遇时,他们将形成一个外边距。合并之后的外边距的高度等于2个发生合并的外边距的高度中的较大值。
2)解决高度塌陷问题
3)清除浮动
4)左侧固定栏,右侧自适应栏
IFC(Inline Formatting Contexts)行内级格式化上下文
这是MDN上的解释:
行内格式化上下文是一个网页的渲染结果的一部分。其中,各行内框(inline boxes)一个接一个地排列,其排列顺序根据书写模式(writing-mode)的设置来决定:
- 对于水平书写模式,各个框从左边开始水平地排列
- 对于垂直书写模式,各个框从顶部开始水平地排列
1、如何创建IFC
块级元素中仅包含内联级别元素,形成条件非常简单,需要注意的是当IFC中有块级元素插入时,会产生两个匿名块将父元素分割开来,产生两个IFC。
2、IFC布局规则
在一个IFC内,子元素是水平方向横向排列的,并且垂直方向起点为元素顶部。
子元素只会计算横向样式空间,【padding
、border
、margin
】,垂直方向样式空间不会被计算,【padding
、border
、margin
】。
在垂直方向上,子元素会以不同形式来对齐(vertical-align
)
能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的行框(line box
)。行框的宽度是由包含块(containing box
)和与其中的浮动来决定。
IFC中的line box
一般左右边贴紧其包含块,但float元素会优先排列。
IFC中的line box
高度由 CSS 行高计算规则来确定,同个IFC
下的多个line box
高度可能会不同。
当 inline boxes
的总宽度少于包含它们的line box
时,其水平渲染规则由 text-align
属性值来决定。
当一个inline box
超过父元素的宽度时,它会被分割成多个boxes
,这些boxes
分布在多个line box
中。如果子元素未设置强制换行的情况下,inline box
将不可被分割,将会溢出父元素。
3、IFC应用场景
1)元素水平居中
当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。
2)多行文本水平垂直居中
创建一个IFC,然后设置其
vertical-align:middle
,其他行内元素则可以在此父元素下垂直居中。
GFC(Grid Formatting Contexts)栅格格式化上下文
当为一个元素设置display
值为grid
或者为inline-grid
的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器grid container
上定义网格定义行grid definition rows
和网格定义列grid definition columns
属性各在网格项目grid item
上定义网格行grid row
和网格列grid columns
为每一个网格项目grid item
定义位置和空间。
1、GFC布局规则
通过在网格容器(grid container
)上定义网格定义行(grid definition rows
)和网格定义列(grid definition columns
)属性各在网格项目(grid item
)上定义网格行(grid row
)和网格列(grid columns
)为每一个网格项目(grid item
)定义位置和空间(具体可以在MDN上查看)
2、GFC应用场景
1)网格布局
FFC(Flex Formatting Contexts)弹性格式化上下文
flex布局提供一种更加有效的方式来进行容器内的项目布局,以适应各种类型的显示设备和各种尺寸的屏幕,使用Flex box布局实际上就是声明创建了FFC(自适应格式上下文)
1、如何触发FFC
当 display
的值为 flex
或 inline-flex
时,将生成弹性容器(Flex Containers), 一个弹性容器为其内容建立了一个新的弹性格式化上下文环境(FFC)
2、FFC布局规则
- 设置为
flex
的容器被渲染为一个块级元素 - 设置为
inline-flex
的容器被渲染为一个行内元素 - 弹性容器中的每一个子元素都是一个弹性项目。弹性项目可以是任意数量的。弹性容器外和弹性项目内的一切元素都不受影响。简单地说,Flexbox 定义了弹性容器内弹性项目该如何布局
**⚠️注意:**FFC布局中,float、clear、vertical-align属性不会生效。
3、FFC应用场景
1)弹性布局