BFC(Block formatting content),中文的翻译是:块级格式化上下文。
W3C 官方对于 BFC 的介绍:BFC
它决定了元素如何对其内容进行定位,以及与其它元素的关系和相互作用,当涉及到可视化布局时,Block Formatting Context
提供了一个环境,HTML
在这个环境中按照一定的规则进行布局。
简单解释一下:你可以把BFC
理解为一种属性,一种类似于box-sizing
的可以决定元素进行何种布局规则的属性(比如BFC
规定上下margin
需要重叠)。
BFC 下遵循什么布局规则?
上面提到,W3C 说BFC
它决定了元素如何对其内容进行定位,以及与其它元素的关系和相互作用,HTML
在这个环境中按照一定的规则进行布局。那么,BFC 下到底遵循什么布局规则?
BFC 的布局规则 👇
BFC
就是一个块级元素,块级元素会在垂直方向一个接一个的排列BFC
就是页面中的一个隔离的独立容器,容器里的标签不会影响到外部标签- 垂直方向的距离由
margin
决定, 属于同一个BFC
的两个相邻的标签外边距会发生重叠 - 计算
BFC
的高度时,浮动元素也参与计算
开发中我们经常遇见的“问题”
第一种:float 元素和普通元素重叠问题
正常渲染机制,浮动节点脱离文档流,不和普通元素产生交互和位置计算。
第二种,上下 margin 重叠
上下当元素上下 margin 重叠后,最后的 margin 距离并不是 margin+margin。而是取最大值。
第三种:内部节点 float 导致父节点高度塌陷
父元素并没有被子元素撑开,因为子元素设置了 float 属性。
请留意这三个案例,下面我们将利用 BFC 的特性解决这三个问题。
看到这里有一个问题:这些是 bug 吗?是最初 html/css 设计上的漏洞吗?
并不是,他们只是遵循了一套布局逻辑而已。
而 BFC 就是让当前元素去遵循另一套渲染逻辑。
触发 BFC 的条件
- 设置了 float 并且值不为 none 的元素
- 设置了 overflow 并且值不为 visible
- 设置了 display 且值为:flex/flow-root/tab-row/tab-row-grounp/grid/inline_block/inline_flex/inline_grid/inline_table/grid/table/table-caption/table-cell
- 设置了 position 并且值为 fixed 或者 absolute
根元素 < html >自带 BFC
BFC
就是一个块级元素,块级元素会在垂直方向一个接一个的排列BFC
就是页面中的一个隔离的独立容器,容器里的标签不会影响到外部标签- 垂直方向的距离由 margin 决定, 属于同一个
BFC
的两个相邻的标签外边距会发生重叠 - 计算
BFC
的高度时,浮动元素也参与计算
BFC 能解决什么问题?
记得我们上面提到的那几个"问题"吗?
BFC
可以解决,margin
重叠,普通节点和浮动节点相互覆盖。内部节点浮动导致的高度塌陷。
案例
使用 BFC 解决子元素浮动导致父元素高度塌陷的机制
注意,上面提到 BFC 的其中一个规则:计算BFC
的高度时,浮动元素也参与计算。parent 的 display:flex 可以触发 BFC,并且 children 元素是一个浮动元素,所以 parent 元素并没有高度塌陷。
margin 重叠机制
但是上面提到BFC
的其中一个规则: 垂直方向的距离由margin
决定, 属于同一个BFC
的两个相邻的标签外边距会发生重叠,所以在一般情况下,两个元素的上下外边距重叠时候不是相加,而是取最大值。
既然在同一个BFC
中,元素外边距会重叠。那么,如果我们让两个元素中的其中一进入另一个 BFC 布局。是不是就可以不重叠margin
了?
在.box2
的外部再套一个div
,并设置一个可以触发BFC
的属性(display:inline-block
)。这样,就不会产生margin
重叠了。
普通元素和浮动元素相互重叠的机制
box1
设置了浮动,原本box2
应该被浮动影响挤压,但是box2
使用overflow:hidden
触发了BFC
,所以没被 box1 浮动影响。
所以,BFC 是什么?他只是一个由某些属性可以触发的一种可以决定元素在 HTML 中如何进行布局和元素之间交互的一个抽象概念而已
END