BFC是什么
BFC全称是Block Formatting Context,即块格式化上下文。它是CSS2.1规范定义的,关于CSS渲染定位的一个概念。
视觉格式化模型
视觉格式化模型(visual formatting model)是用来处理文档并将它显示在视觉媒体上的机制,它也是CSS中的一个概念。
视觉格式化模型定义了盒(Box)的生成,盒主要包括了块盒、行内盒、匿名盒(没有名字不能被选择器选中的盒)以及一些实验性的盒(未来可能添加到规范中)。盒的类型由display
属性决定。
块盒(block box)
- 当元素的CSS属性
display
为block
,list-item
或table
时,它是块级元素 block-level; - 视觉上呈现为块,竖直排列;
- 块级盒参与(块格式化上下文);
- 每个块级元素至少生成一个块级盒,称为主要块级盒(principal block-level box)。一些元素,比如
<li>
,生成额外的盒来放置项目符号,不过多数元素只生成一个主要块级盒。
行内盒(inline box)
-
当元素的CSS属性
display
的计算值为inline
,inline-block
或inline-table
时,称它为行内级元素; -
视觉上它将内容与其它行内级元素排列为多行;典型的如段落内容,有文本(可以有多种格式譬如着重),或图片,都是行内级元素;
-
行内级元素生成行内级盒(inline-level boxes),参与行内格式化上下文(inline formatting context)。同时参与生成行内格式化上下文的行内级盒称为行内盒(inline boxes)。所有
display:inline
的非替换元素生成的盒是行内盒; -
不参与生成行内格式化上下文的行内级盒称为原子行内级盒(atomic inline-level boxes)。这些盒由可替换行内元素,或
display
值为inline-block
或inline-table
的元素生成,不能拆分成多个盒;置换元素(replaced element)
一个内容不受CSS视觉格式化模型控制,CSS渲染模型并不考虑对此内容的渲染,且元素本身一般拥有固有尺寸(宽度,高度,宽高比)的元素,被称之为置换元素。这类元素,浏览器根据元素的标签和属性,来决定元素的具体显示内容。
常见的置换元素有这些:img,input,textarea,select,button
等除置换元素之外,所有的元素都是非置换元素。
匿名盒(anonymous box)xj
匿名盒又分匿名块盒与匿名行内盒,因为匿名盒没有名字,不能利用选择器来选择它们,所以它们的所有属性都为inherit
或初始默认值;
三个定位方案
在定位的时候,浏览器就会根据元素的盒类型和上下文对这些元素进行定位,可以说盒就是定位的基本单位。定位时,有三种定位方案,分别是常规流,浮动以及绝对定位。
常规流(Normal flow)
- 在常规流中,盒一个接着一个排列;
- 在块级格式化上下文里面, 它们竖着排列;
- 在行内格式化上下文里面, 它们横着排列;
- 当
position
为static
或relative
,并且float
为none
时会触发常规流; - 对于静态定位(static positioning),
position: static
,盒的位置是常规流布局里的位置; - 对于相对定位(relative positioning),
position: relative
,盒偏移位置由这些属性定义top
,bottom
,left
andright
。即使有偏移,仍然保留原有的位置,其它常规流不能占用这个位置。
浮动(Floats)
- 盒称为浮动盒(floating boxes);
- 它位于当前行的开头或末尾;
- 这导致常规流环绕在它的周边,除非设置 clear 属性;
绝对定位(Absolute positioning)
- 绝对定位方案,盒从常规流中被移除,不影响常规流的布局;
- 它的定位相对于它的包含块,相关CSS属性:
top
,bottom
,left
及right
; - 如果元素的属性
position
为absolute
或fixed
,它是绝对定位元素; - 对于
position: absolute
,元素定位将相对于最近的一个relative
、fixed
或absolute
的父元素,如果没有则相对于body
;
外边距叠加(margin collapse)
两个或多个毗邻的普通流中的盒子(可能是父子元素,也可能是兄弟元素)在垂直方向上的外边距会发生叠加,这种形成的外边距称之为外边距叠加。注意浮动元素和绝对定位元素的外边距不会折叠。
产生外边距折叠的场景:
-
相邻元素之间
毗邻的两个元素之间的外边距会折叠(除非后一个元素需要清除之前的浮动)。
-
父元素与其第一个或最后一个子元素之间
-
空的块级元素
一些需要注意的地方:
- 上述情况的组合会产生更复杂的外边距折叠。
- 即使某一外边距为0,这些规则仍然适用。因此就算父元素的外边距是0,第一个或最后一个子元素的外边距仍然会“溢出”到父元素的外面。
- 如果参与折叠的外边距中包含负值,折叠后的外边距的值为最大的正边距与最小的负边距(即绝对值最大的负边距)的和。
- 如果所有参与折叠的外边距都为负,折叠后的外边距的值为最小的负边距的值。这一规则适用于相邻元素和嵌套元素。
块格式化上下文
块格式上下文是页面CSS 视觉渲染的一部分,用于决定块盒子的布局及浮动相互影响范围的一个区域。
BFC的触发方法:
- 根元素或其它包含它的元素;
- 浮动 (元素的float不为none);
- 绝对定位元素 (元素的position为absolute或fixed);
- 行内块inline-blocks(元素的 display: inline-block);
- 表格单元格(元素的display: table-cell,HTML表格单元格默认属性);
- overflow的值不为visible的元素;
- 弹性盒 flex boxes (元素的display: flex或inline-flex);
但其中,最常见的就是overflow:hidden
、float:left/right
、position:absolute
。也就是说,每次看到这些属性的时候,就代表了该元素触发了一个BFC了。
BFC的范围
BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。
BFC的布局规矩
-
内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流);
-
处于同一个BFC中的元素相互影响,可能会发生margin collapse;
-
每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此;
-
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;
-
计算BFC的高度时,考虑BFC所包含的所有元素,浮动元素也参与计算;
-
浮动盒区域不叠加到BFC上;
浮动定位和清除浮动时只会应用于同一个BFC内的元素。浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。外边距折叠也只会发生在属于同一BFC的块级元素之间。
BFC用途
- 清除浮动
- 防止垂直margin合并
- 布局:自适应两栏布局
IFC
Inline Formatting Contexts,也就是“内联格式化上下文”。
触发条件
- 块级元素中仅包含内联级别元素
IFC布局规则
- IFC中的line box一般左右都贴紧整个IFC,但是会因为float元素而扰乱。float元素会位于IFC与与line box之间,使得line box宽度缩短。
- IFC中时不可能有块级元素的,当插入块级元素时(如p中插入div)会产生两个匿名块与div分隔开,即产生两个IFC,每个IFC对外表现为块级元素,与div垂直排列。
IFC用途
- 水平居中:当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。
- 垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。
网友评论