详解什么是BFC和BFC能解决什么问题
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
转载自:https://juejin.cn/post/7199913007216115749