BFC与IFC
在解释BFC是什么之前,我们先介绍另外两个概念:Box和Formatting Context。
Box
“Box”这个单词的意思就是“盒子”。
我们的网页是由很多个HTML元素组成的。了解过CSS盒模型的都应该知道,里面有一个概念就是把网页里一个一个的元素看作是一个一个的盒子,一个网页就可以看作是由很多个盒子组成的,换一个洋气的说法,那么就是——
一个网页是由很多个Box组成的。
同时,我们的元素又分为块级元素和行内元素,而它们两者之间又可以通过CSS属性“display”来相互进行转换。
所以,我们HTML元素的类型和“display”的属性,决定了我们Box(盒子)的类型。而不同类型的Box会参与到不同的Formatting Context中,不同的Formatting Context会让Box内的元素用不同的方式去渲染。
Formatting Context
“格式化上下文”,Formatting Context 是W3C在CSS2.1中提出的一个概念。
什么是“上下文”?
上下文定义了元素在CSS中所处的环境。
什么是“格式化”?
格式化则表明了在这个环境中,处于此环境中的元素都应该被初始化。
所以,“格式化上下文”实际上它是指一块独立的渲染区域,在它的渲染区域里,有一套自己的渲染规则,决定着内部子元素如何定位布局以及它自身与其他元素之间的关系和相互作用。
我们现在比较常见的Formatting Context是Block Formatting Context(BFC)和 Inline Formatting Context(IFC)。
CSS2.1中只有 BFC 和 IFC,CSS3 中还增加了 GFC 和 FFC。
BFC(Block Formatting Context)块级格式化上下文
结合上面提到的Formatting Context的概念,那么BFC的意思其实就是 一个只有块级元素参与的独立渲染区域。
举个栗子:
我们把我们的页面看作是一个集装箱,现在我和你两个人都分别有一批货物要放进集装箱内。当我第一个进去放的时候,我可以选择随意的摆放我的货物,横着排,竖着排,斜着排。但是我摆放货物的位置,就直接影响到了你后面进来摆放货物的位置。所以,我们需要一个办法,既能让我按照我自己的规则去摆放我的货物,同时又不影响你的货物位置的摆放。
于是我在集装箱里用笔划分出了一块属于我的区域,在我的这块区域里,我可以按照我的规则去摆放我的货物,不管我怎么摆放,你的货物都只能从我的区域线外开始摆放。所以,我的货物的摆放位置对你没有任何影响。
那么,我用笔划分出来的这一块属于我的区域,就是我的BFC。
BFC的定义
BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域(创建了BFC的元素就是一个独立的盒子),只有Block-level box参与, 它规定了内部的Block-level Box如何布局,且与区域外部其他元素互不影响。
怎么形成BFC
- 根元素
- float属性不为none
- position为absolute或fixed
- display为inline-block, table-cell, table-caption, flex, inline-flex
- overflow不为visible
BFC的布局规则
我们回到集装箱的栗子。
虽然我有我自己的一块区域了,但是在我的区域里也有一套我自己的一套摆放规则。比如易碎物品不能放在其他箱子下面,容易受潮的货物又应该放在什么位置等等......
所以,在BFC里也有一套他的布局规则。
- 内部的Box会在垂直方向,一个接一个地放置。
- Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发⽣生重叠。
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box重叠。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算
- 需要触发,才能实现独立的运行环境
IFC(Inline Formatting Context)行内格式化上下文
IFC和BFC一样,既不是属性也不是元素,而是一种环境,一种上下文。
怎么形成IFC
只要有行内元素的出现,就会产生IFC。
IFC的布局规则
- 框(boxes)一个接一个地水平排列,起点是包含块的顶部;
- 水平方向上的margin,border和padding在框之间得到保留;
- 框在垂直方向上可以以不同的方式对齐:它们的顶部或底部对齐,或根据其中文字的基线对齐;
- 包含那些框的长方形区域,会形成一行,叫做行盒(line box);
- 一个行框的宽度由包含它的元素的宽度和包含它的元素里面有没有float元素来决定,高度的确定由行高度计算规则决定;
line box行盒
一横排的行内元素在垂直方向上有很多种对齐方式:底部或顶部对齐,或者根据文字的基线对齐。他们对齐后的外围形成的一个矩形的区域,就叫做一个line box(行盒)。
除了IFC以外,对于inline-level box(行内元素)排版而言另一个重要的对象,就是line box。
一个line box的宽度由包含它的元素的宽度和包含它的元素里面有没有float元素来决定,高度的确定由行高计算规则决定。
其实这句话解释了为什么行内元素是不能设置垂直方向的padding、margin等的原因。因为即使设置了,也不会影响line box的高度,可能会在每个浏览器的表现各异,但大多数不会达到预期的效果。

浙公网安备 33010602011771号