块格式化上下文(Block Formatting Context,BFC) 是 Web 页面的可视 CSS 渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
下列方式会创建块格式化上下文:
- 根元素(
<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
不为auto,包括
column-count
为1
) column-span
为all
的元素始终会创建一个新的 BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。
注释:
display:flow-root
该元素生成一个块元素框,该框可建立新的块格式化上下文,定义格式化根所在的位置
注释:
contain
属性允许开发者声明当前元素和它的内容尽可能的独立于 DOM 树的其他部分。这使得浏览器在重新计算布局、样式、绘图、大小或这四项的组合时,只影响到有限的 DOM 区域,而不是整个页面,可以有效改善性能。(注释:不仅仅是个声明,会影响元素的渲染行为。)
strict:表示除了 style 外的所有的包含规则应用于这个元素。等价于 contain: size layout paint。
content:表示这个元素上有除了 size 和 style 外的所有包含规则。等价于 contain: layout paint。
size:表示这个元素的尺寸计算不依赖于它的子孙元素的尺寸。
layout:表示元素外部无法影响元素内部的布局,反之亦然。
style:表示那些同时会影响这个元素和其子孙元素的属性,都在这个元素的包含范围内。
paint:表示这个元素的子孙节点不会在它边缘外显示。如果一个元素在视窗外或因其他原因导致不可见,则同样保证它的子孙节点不会被显示。
注释:
display:inline-flex
该元素的行为类似于内联元素,并根据 flexbox 模型布局其内容。(注释:和inline-block相比,inline-flex的内容默认不换行)
注释:
column-count
、column-width
多列布局,类似新闻分栏。
注释:
column-span
元素跨越所有列
块格式化上下文包含创建它的元素内部的所有内容.
注释:块格式化上下文限定了浮动、清楚浮动、外边距折叠的范围
块格式化上下文对浮动定位(参见 float
)与清除浮动(参见 clear
)都很重要。浮动定位和清除浮动时只会应用于同一个 BFC 内的元素。浮动不会影响其它 BFC 中元素的布局,而清除浮动只能清除同一 BFC 中在它前面的元素的浮动。外边距折叠(Margin collapsing)也只会发生在属于同一 BFC 的块级元素之间。
范例
让浮动内容和周围的内容等高
注释:块格式上下文内部的浮动元素会撑开块格式上下文
为了更好的理解 BFC,我们先看看下面这些。
在下面的例子中,我们让 <div>
元素浮动,并给它一个边框效果。<div>
里的内容现在已经在浮动元素周围浮动起来了。由于浮动的元素比它旁边的元素高,所以 <div>
的边框穿出了浮动。正如我们在这篇文章中 guide to in-flow and out of flow elements 解释的,浮动脱离了文档流,所以 <div>
的 background
和 border
仅仅包含了内容,不包含浮动。
使用overflow: auto
使用 overflow
来创建一个新的 BFC,是因为 overflow
属性告诉浏览器你想要怎样处理溢出的内容。当你使用这个属性只是为了创建 BFC 的时候,你可能会发现一些不想要的问题,比如滚动条或者一些剪切的阴影,需要注意。
使用display: flow-root
一个新的 display
属性的值,它可以创建无副作用的 BFC。在父级块中使用 display: flow-root
可以创建新的 BFC。
Exclude external floats
注释:块格式上下文与非浮动元素交互时表现为块元素,会占满整行;但与浮动元素交互式表现更像弹性元素,会保持和弹性元素在同一行尽量占满该行剩余的空间。
In the following example, we are using display:flow-root
and floats to implement double columns layout, beacuse an element in the normal flow that establishes a new BFC must not overlap the margin box of any floats in the same block formatting context as the element itself.
下例使用display:flow-root
和float
实现双列布局,因为在正常流程中建立新BFC的元素必须与该元素本身在同一块格式上下文中不与任何浮点数的边距框重叠。??
HTML
<section>
<div>Try to resize this outer float</div>
<div><p>Normal</p></div>
</section>
<section>
<div>Try to resize this outer float</div>
<div><p><code>display:flow-root</code><p></div>
</section>
CSS
section {
height:150px;
}
.box {
background-color: rgb(224, 206, 247);
border: 5px solid rebeccapurple;
}
.box[style] {
background-color: aliceblue;
border: 5px solid steelblue;
}
.float {
float: left;
margin-right:25px;
200px;
height: 100px;
background-color: rgba(255, 255, 255, .75);
border: 1px solid black;
padding: 10px;
}
外边距塌陷
创建新的 BFC 避免两个相邻 <div>
之间的 外边距合并 问题
HTML
<div></div>
<div>
<div>red inner</div>
</div>
CSS
.blue, .red-inner {
height: 50px;
margin: 10px 0;
}
.blue {
background: blue;
}
.red-outer {
overflow: hidden;
background: red;
}