聊一聊BFC

什么是FC

在说BFC之前我们先说一下什么是FC,FC的全称是Formatting Context(格式化上下文),元素在标准流里面都是属于一个FC的。

在标准流中一个元素要么属于块级格式化上下文(BFC),要么属于行内级格式化上下文(IFC),而一个块级元素是属于块级格式化上下文(BFC)的。行内级元素则是属于行内级格式化上下文(IFC)的。

哪些情况下会创建BFC

(1)根元素 < html >

(2)浮动元素(元素的 float 不是 none)

(3)绝对定位元素(元素的 position 为 absolute 或 fixed)

(4)行内块元素(元素的 display 为 inline-block)

(5)表格单元格(元素的 display 为 table-cell,HTML表格单元格默认为该值),表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)

(6)匿名表格单元格元素(元素的 display 为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot 的默认属性)或 inline-table

(7)overflow的值不为 visible 的块元素

(8)弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)

(9)网格元素(display 为 grid 或 inline-grid 元素的直接子元素)

(10)display 值为 flow-root 的元素

BFC怎样作用于元素

(1)在一个块级格式化上下文中,盒子在垂直方向上一个挨着一个排布。

(2)两个相邻盒子之间的垂直距离由margin决定

(3)在一个块级格式化上下文中相邻两个盒子之间的垂直margin会进行合并

(4)在一个BFC中,每个元素的左边缘是紧挨着包含块的左边缘

BFC的作用

(一) 解决折叠问题

我们来看以下一段代码的表现:

很明显2个div的上下margin被折叠了。怎么解决这个问题呢? 我们注意到,上面的第3点说,在一个块级格式化上下文中相邻两个盒子之间的垂直margin会进行合并,如果我们让2个盒子不在同一个BFC中,这个问题不就解决了吗?然后我们再看看可以创建BFC的10种情况,我们利用overflow的值不为 visible 的块元素可以创建一个BFC这一条,分别给2个块级元素加上overflow:auto属性。如下:

但是,我们仍然可以看到,问题并没有解决,导致这个问题的原因在于,box1和box2虽然自身都创建了一个BFC,但是他们自身仍然处于同一个BFC中,这个BFC就是html元素了。要解决这个问题,是让box1和box2处于不同的BFC中。我们给box1套一个外层的div,然后给这个div的overflow属性设置为auto。让box1处在container块的BFC中,而box2仍然处于html的BFC中,这样,问题就可以得到解决了。如下:

(二) 解决浮动的高度坍塌问题

我们来看一下下面的代码:

在浏览器显示的结果如下:

可以看到,我们虽然给包含块container设置了背景,但是包含块并没有高度,也就是高度坍塌了,出现这个问题的原因是浮动元素不会向父级元素汇报自身高度。

解决浮动元素高度坍塌问题的方法也很简单,只要让浮动元素的包含块形成一个BFC就可以了,如下:

结果如下: 可以看到包含块有高度了。

为什么让包含块形成一个BFC就可以解决高度坍塌问题呢?

一个高度为auto的块级格式化上下文的高度是这样计算的:

(1)如果这个块只有行内级子元素,那么它的高度是最上面的行盒的顶部和最下面的行盒的底部的距离

(2)如果有块级子元素,那么它的高度是最上面的块级盒子的margin-top边缘和最下面的块级盒子的margin-bottom 边缘之间的距离。

(3)如果有绝对定位子元素将会被忽略,而相对定位的盒子将会被考虑在高度计算之内,但是并不会考虑相对定位盒子的offset值

(4)另外,如果元素有浮动的后代元素,其底部边缘低于元素的底部内容边缘,(包含块)则会增加高度以包含这些边缘。

注意到以上第4点,可以看到是外部形成BFC的包含块主动包裹浮动子块,而不是子块把高度汇报给了包含块。这就是BFC能解决浮动高度坍塌的原因。但是由于形成BFC的包含块高度的计算仍然会忽略绝对定位子元素,所以即使绝对定位子元素的高度坍塌问题同样是由于子元素不向父元素汇报自身高度,但是BFC并不能解决绝对定位元素高度坍塌问题。

相关推荐
deli00713 分钟前
Skill 怎么写才被 Agent 命中?18 条规则做成 SKILL.md 校验器,规范样例 92 分
前端
Hum8le13 分钟前
CTF题目《easy_web》(安洵杯 2019 变种 Web)
前端·安全·web安全
coding漫漫长路14 分钟前
二值化后还剩1212个黑点,OCR却认成了乱码
前端
不可能片场15 分钟前
AI视频口型对齐 用音频驱动说话镜头
前端·electron
Lank_M16 分钟前
OCR一个字没认错,倾斜2.5°却把行序排乱了
前端
daols8819 分钟前
vue 表格组件 vxe-table 实现自定义多行编辑功能
前端·javascript·vue.js·vxe-table
不要试图纠正别人23 分钟前
别让大模型算钱:我把优惠券组合优化写成了确定性算法
前端
IT_Octopus1 小时前
【零基础入门 LLM 开发 · Day 11】:ChatOpenAI vs init_chat_model——一行换供应商
java·前端·javascript
柚yuzumi1 小时前
React 19 Hooks 入门:函数组件的四大法宝 (useState / useEffect / useRef / useContext)
前端·javascript·架构
deli0071 小时前
撒下 200 个种子点,平面为什么自己长成蜂窝?Voronoi 图实验室
前端