当前位置:网站首页>BFC详解(Block Formmating Context)
BFC详解(Block Formmating Context)
2022-08-05 05:14:00 【汪鸿的好朋友】
BFC 是一个页面的渲染区域的一部分,它是默认布局模式:标准文档流 (Normal Flow) 的活动区域 和 浮动元素的活动区域。
我们可以将网页的渲染看成一颗 BFC 树(便于理解),这颗树的根元素就是 <html>
,在这颗树下,有很多其他的子 BFC 以及 其他布局模式的节点,如 FFC , GFC 和 Table 等。

1. 产生BFC的途径
<html>
标签也就是整个网页本身就是一个最大的 BFC。*float
浮动一个元素会使其脱离标准文档流,这个浮动元素就成了一个单独的 BFC。* 定位对一个元素进行绝对定位 (postion: absolute
) 和固定定位 (position: fixed
) 会使其变成一个BFC。*display
通过display
改变一个元素的内部布局模式,比如:*display: flow-root
,推荐使用这种方式,因为这种方式的目的就是为了产生一个 BFC,而其他方式产生的 BFC 是为了实现其他特定目标而顺带的产生一个 BFC*display: inline-block
与上一条基本等价,因为其全写为:display: inline flow-root
*display: talbe
等与表格布局模式相关的值。overflow
只要overflow
的值不是visible
和clip
,都会产生 BFC。* Flex item,弹性盒的子元素,也就是说对一个盒子使用display: flex
,那么它的子元素都会自动成为一个 BFC。* Grid item,栅格盒的子元素,也就是说对一个盒子使用display: grid
,那么它的子元素都会自动成为一个 BFC。* 多列布局,比如对一个元素设置column-count
或column-wdith
(只要这个值不是auto
),这个元素也会成为一个 BFC。*column-span: all
也会产生一个 BFC。2. 类似BFC但不是BFC的情况
网上有一些文章会说 Flex 和 Grid 也会产生 BFC,其实这是个错误的说法。
因为 Flex 和 Grid 产生的是一个 Flex/Grid formatting context,这个 FFC/GFC 与 BFC 很像,因为它们都是某种特定的布局模式的活动环境,但还是存在一些区别:
在 FFC 和 GFC 内部不会存在浮动子元素,也就是说 FFC 和 GFC 不是浮动元素的活动区域,我们来看个例子:
<div class="container"><p>below is a Flex box</p><div class="flexbox"><div class="float">I am a box assigned float: right</div></div>
</div>
.flexbox {width: 100%;height: 20em;background-color: aquamarine;display: flex;
}
.float {float: right;width: 50%;height: 25%;background-color: aqua;
}
假如浮动元素可以在弹性盒子里活动的话,那么这个浮动盒子应该是靠右的,但实际情况是:

这是因为 Flex 和 Grid 有自己的布局规则,这个规则的优先级是高于浮动的,所以在 Flex 和 Grid 中使用 Float 是不会产生对应效果的。
3. BFC可以用来干什么
上面详细解释了 BFC 的产生途径,这小节讲述 BFC 的主要用途:
3.1 限制浮动元素的活动范围
有时候我们对一个元素内部的子元素使用浮动后,当这个浮动元素的高度比父元素的实际高度更高时,就会出现类似下面的效果:

这种情况发生的原因本质上是因为浮动元素是脱离了标准文档流,父元素和浮动元素实际上是处于两个图层:

在上图中,浮动子元素的活动区域是 外界的BFC,为了解决这个问题,我们需要把父元素变成一个 BFC,让子元素只能在父元素的 BFC 里面活动。

一种解决方法是使用 overflow
把父元素变成一个BFC:

但是这种方法有一个隐藏的问题就是,当父元素里面内容过多的话,会出现滚动条。
并且这种方式具有歧义性:设置 overflow: auto
的意思是让父元素自行安排自己的内容溢出,而我们想要的仅仅只是让父元素成为一个 BFC。
另一种解决方法是使用 display: flow-root
,这只会使父元素变成一个 BFC 而不带其他副作用:

值得一提的是,IE 并不支持这种方式,所以要兼容 IE 就不要采用这种方法。
3.2 解决margin合并问题
有时候当父元素的上边和第一个子元素的上边是紧密贴在一起,两者之间没有任何其他内容的时候,这个时候对子元素设置 margin-top
会影响到父元素,举个例子:
<div class="blue"></div>
<div class="red-outer"><div class="red-inner">red inner</div>
</div>
.blue {background: blue;height: 50px;
}
.red-inner {height: 50px;margin: 10px 0;
}
.red-outer {background: red;
}
这段 CSS 本意是想让 red-inner 离 red-outer10px
远,但实际却是这样的:

红色的 父div 与 蓝色的div 之间产生了一个外边距,而这个边距其实是来自 red inner。
要消除这个影响,可以让 红色的父div 成为一个 BFC。
.red-outer {display: flow-root;
}

4. 总结
- BFC 本质上是 默认布局模式 Normal flow 的活动环境/上下文。
- 使用
display: flow-root
可以无副作用的生成一个 BFC ,但在 IE 中不兼容。
边栏推荐
猜你喜欢
随机推荐
redis复制机制
Database experiment five backup and recovery
第四讲 back propagation 反向传播
实现跨域的几种方式
学习总结week3_1函数
NodeJs接收上传文件并自定义保存路径
第三讲 Gradient Tutorial梯度下降与随机梯度下降
flink部署操作-flink on yarn集群安装部署
对数据排序
Lecture 3 Gradient Tutorial Gradient Descent and Stochastic Gradient Descent
关于基于若依框架的路由跳转
redis事务
DOM及其应用
Flink HA安装配置实战
redis cache clearing strategy
The fourth back propagation back propagation
flink on yarn 集群模式启动报错及解决方案汇总
机器学习(二) —— 机器学习基础
如何停止flink job
day9-字符串作业