阿卡不拉阿卡不拉
Vue3
阿卡的博客
Vue3
阿卡的博客
  • Vue3

    • 快速入门

      • 搭建工程 👌
      • 模板语法
      • 响应式基础
      • 响应式常用 API
      • 计算属性
      • 类与样式绑定
      • 条件和列表渲染
      • 事件处理
      • 表单处理
      • 生命周期
      • 侦听器
      • 组件介绍
      • Props
      • 自定义事件
      • 组件v-model
      • 插槽
      • 前端路由介绍
      • KeepAlive内置组件
      • 状态管理库
      • 组件库介绍
    • 深入本质

      • 虚拟DOM本质
      • 模板的本质
      • 组件树和虚拟DOM树
      • 数据拦截的本质
      • 响应式数据的本质
      • 响应式的本质
      • 响应式和组件渲染
      • 实现响应式系统 1
      • 实现响应式系统 2
      • 图解EFFECT
      • 实现响应式系统 3
      • 手写computed
      • 手写watch
      • 指令的本质
      • 插槽的本质
      • v-model的本质
      • setup 语法标签
      • 组件生命周期
      • keepalive 生命周期
      • keepalive的本质
      • key的本质
    • 细节补充

      • 【Vue】属性透传
      • 【Vue】依赖注入
      • 【Vue】组合式函数 👌
      • 【Vue】自定义指令
      • 【Vue】插件
      • 【Vue】Transition
      • 【Vue】TransitionGroup
      • 【Vue】Teleport
      • 【Vue】异步组件
      • 【Vue】Suspense
      • 【Router】路由模式
      • 【Router】路由零碎知识
      • 【Router】路由匹配语法
      • 【Router】路由组件传参
      • 【Router】内置组件和函数
      • 【Router】导航守卫
      • 【Router】过渡特效
      • 【Router】滚动行为
      • 【Router】动态路由
      • 【State】通信方式总结
      • 【State】Pinia 自定义插件
      • 【场景】封装树形组件
      • 【场景】自定义 ref 实现防抖
      • 【场景】懒加载
      • 【场景】虚拟列表
      • 【场景】虚拟列表优化
      • 【第三方库】VueUse
      • 【第三方库】vuedragable
      • 【第三方库】vue-drag-resize
      • 【第三方库】vue-chartjs
      • 【第三方库】vuelidate
      • 【第三方库】vue3-lazyload
      • 【场景】Websocket 聊天室
      • 【Vite】✨ 认识 Vite👌
      • 【Vite】配置文件 👌
      • 【Vite】✨ 依赖预构建 👌
      • 【Vite】构建生产版本 👌
      • 【Vite】环境变量与模式
      • 【Vite】CLI
      • 【Vite】Vite 插件
  • 笔面试

    • HTML

      • HTML 面试题汇总
      • 文档声明
      • 语义化
      • W3C 标准组织
      • SEO
      • iframe
      • 微格式
      • 替换元素
      • 页面可见性
    • CSS

      • CSS 面试题汇总
      • CSS 单位总结
      • 居中方式总结
      • 隐藏元素方式总结
      • 浮动
      • 定位总结
      • BFC
      • CSS 属性计算过程
      • CSS 层叠继承规则总结
      • @import 指令
      • CSS3 calc 函数
      • CSS3 媒体查询
      • 过渡和动画事件
      • 渐进增强和优雅降级
      • CSS3 变形
      • 渐进式渲染
      • CSS 渲染性能优化
      • 层叠上下文
      • CSS3 遮罩
    • JavaScript

      • JavaScript 面试题汇总
      • ✨ let、var、const 的区别
      • JS中的数据类型
      • 包装类型
      • 数据类型的转换
      • 运算符
      • ✨ 原型链
      • ✨ this 指向
      • ✨ 垃圾回收与内存泄漏
      • ✨ 执行栈和执行上下文
      • ✨ 作用域和作用域链
      • ✨ 闭包
      • DOM 事件的注册和移除
      • DOM 事件的传播机制
      • 阻止事件默认行为
      • 递归
      • ✨ 属性描述符
      • class 和构造函数区别
      • 浮点数精度问题
      • 严格模式
      • ✨ 函数防抖和节流
      • ✨ WeakSet 和 WeakMap
      • ✨ 深浅拷贝
      • 函数柯里化
      • Node 事件循环
      • 尺寸和位置
    • 浏览器

      • 浏览器面试题汇总
      • ✨ 浏览器的渲染流程
      • ✨ 资源提示关键词
      • 浏览器的组成部分
      • IndexedDB
      • ✨ File API
      • ✨ 浏览器缓存
      • ✨ 浏览器跨标签页通信
      • Web Worker
    • 网络

      • 网络面试题汇总
      • 五层网络模型 👌
      • 常见请求方法 👌
      • ✨cookie👌
      • 面试题
      • 加密
      • ✨JWT👌
      • ✨ 同源策略及跨域问题 👌
      • 文件上传
      • ✨ 输入 url 地址之后
      • 文件下载
      • ✨ session
      • ✨ TCP
      • ✨ CSRF 攻击
      • ✨XSS 攻击 👌
      • ✨ 网络性能优化
      • 断点续传
      • 域名和 DNS
      • SSL、TLS、HTTPS 的关系
      • ✨ HTTP 各版本差异 👌
      • HTTP 缓存协议
      • ✨ WebSocket
    • 工程化

      • CMJ 和 ESM
      • npx
      • ESLint
    • Vue2

      • Vue 面试题汇总相关
      • 组件通信方式总结
      • 虚拟 DOM
      • v-model
      • 数据响应式原理
      • diff
      • 生命周期详解
      • computed
      • 过滤器
      • 作用域插槽
      • 过度和动画
      • 优化
      • keep-alive
      • 长列表优化
      • 其他 API
      • 模式和环境变量
      • 更多配置
      • 更多命令
      • 嵌套路由
      • 路由切换动画
    • Vue3

      • ✨ Vue3 整体变化 👌
      • ✨ Vue3 响应式变化 👌
      • ✨ nextTick 实现原理 👌
      • 两道代码题 👌
      • Vue 运行机制
      • 渲染器核心功能
      • 事件绑定与更新

BFC

经典真题

  • 介绍下 BFC 及其应用
  • 介绍下 BFC、IFC、GFC 和 FFC

搞懂各种 FC

一看到 BFC、IFC、GFC 和 FFC,大家可能会想到 KFC。

然而这里所说的 xFC 和 KFC 没有任何关系。

那么这些 FC 究竟是啥呢?

不着急,我们先搞懂一个,后面的陆陆续续也就融会贯通了。

我们首先就来看这个 BFC,英语全称 Block formatting contexts,翻译成中文就是“块级格式化上下文”。

简单来说,就是页面中的一块渲染区域,并且有一套属于自己的渲染规则,它决定了元素如何对齐内容进行布局,以及与其他元素的关系和相互作用。 当涉及到可视化布局的时候,BFC 提供了一个环境,HTML 元素在这个环境中按照一定规则进行布局。

再简短一点,那就是:BFC 是一个独立的布局环境,BFC 内部的元素布局与外部互不影响

这就好比你在你自己家里面,你想怎么摆放你的家具都可以,你家的家具布局并不会影响邻居家的家具布局。

当然,虽然说 BFC 是一个独立的布局环境,里外不影响,但也不是意味着布局没有章法,基本的规矩还是要有的。

例如,BFC 的布局规则有如下几条:

  1. 内部的 Box 会在垂直方向一个接着一个地放置。
  2. Box 垂直方向上的距离由 margin 决定。属于同一个 BFC 的两个相邻的 Box 的 margin 会发生重叠。
  3. 每个盒子的左外边框紧挨着包含块的左边框,即使浮动元素也是如此。
  4. BFC 的区域不会与浮动 Box 重叠。
  5. BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
  6. 计算 BFC 的高度时,浮动子元素也参与计算。

诶??

这好像在我们的 body 元素里面,盒子天然就是这样的布局规则呀?

没错,实际上在一个标准流中 body 元素就是一个天然的 BFC。

那么如果其他区域,我想单独设置成一个 BFC,该怎么办呢?这里记录了一些常见的方式:

元素或属性属性值
根元素
floatleft、right
postionabsolute、fixed
overflowauto、scroll、hidden
displayinline-block、table-cell

上面只记录了一些常见的方式,完整的 BFC 触发方式可以参阅:

区块格式化上下文 - CSS:层叠样式表 | MDN

那么块级格式化上下文有啥具体的用处呢?我们来看几个场景

  1. 解决浮动元素令父元素高度坍塌的问题
<div class="father">
    <div class="son"></div>
</div>
.father {
    border: 5px solid;
}
.son {
    width: 100px;
    height: 100px;
    background-color: blue;
    float: left;
}

在上面的代码中,父元素的高度是靠子元素撑起来的,但是一旦我们给子元素设置了浮动,那么父元素的高度就塌陷了。如下:

此时我们就可以将父元素设置成一个 BFC,例如:

.father {
    border: 5px solid;
    overflow: hidden;
    /* 将父元素设置为一个 BFC */
}
.son {
    width: 100px;
    height: 100px;
    background-color: blue;
    float: left;
}

效果:可以看到由于父元素变成 BFC,高度并没有产生塌陷了,其原因是在计算 BFC 的高度时,浮动子元素也参与计算

  1. 非浮动元素被浮动元素覆盖
<div class="box1"></div>
<div class="box2"></div>
.box1 {
    width: 100px;
    height: 50px;
    background-color: red;
    float: left;
}
.box2 {
    width: 50px;
    height: 50px;
    background-color: blue;
}

在上面的代码中,由于 box1 设置了浮动效果,所以会脱离标准流,自然而然 box2 会往上面跑,结果就被高度和自己一样的 box1 给挡住了。

接下来我们设置 box2 为 BFC,如下:

.box1 {
    width: 100px;
    height: 50px;
    background-color: red;
    float: left;
}
.box2 {
    width: 50px;
    height: 50px;
    background-color: blue;
    overflow: hidden;
}

效果:由于 BFC 的区域不会与浮动 box 重叠,所以即使 box1 因为浮动脱离了标准流,box2 也不会被 box1 遮挡

基于此特点,我们就可以制作两栏自适应布局,方法就是给固定栏设置固定宽度,给不固定栏开启 BFC。

<div class="left">导航栏</div>
<div class="right">这是右侧</div>
* {
    margin: 0;
    padding: 0;
}
.left {
    width: 200px;
    height: 100vh;
    background-color: skyblue;
    float: left;
}

.right {
    width: calc(100% - 200px);
    height: 100vh;
    background-color: yellowgreen;
}

效果:在上面的代码中,我们要设置两栏布局,左边栏宽度固定,右边栏自适应。结果我们发现右侧出现了空白

究其原因就是右侧区域与浮动盒子重叠了

修改 .right 部分的代码,添加 overflow:hidden 使其成为一个 BFC:

.right {
    width: calc(100% - 200px);
    height: 100vh;
    background-color: yellowgreen;
    overflow: hidden;
}

效果:因为 BFC 的区域不会与浮动 Box 重叠,所以右侧空白没有了

  1. 外边距垂直方向重合的问题

BFC 还能够解决 margin 折叠的问题,例如:

<div class="box1"></div>
<div class="box2"></div>
* {
    margin: 0;
    padding: 0;
}
.box1 {
    width: 100px;
    height: 100px;
    background-color: red;
    margin-bottom: 10px;
}
.box2 {
    width: 100px;
    height: 100px;
    background-color: blue;
    margin-top: 10px;
}

效果:

此时我们可以在 box2 外部再包含一个 div,并且将这个 div 设置为 BFC,如下:

<div class="box1"></div>
<div class="container">
    <div class="box2"></div>
</div>
* {
    margin: 0;
    padding: 0;
}

.box1 {
    width: 100px;
    height: 100px;
    background-color: red;
    margin-bottom: 10px;
}
.box2 {
    width: 100px;
    height: 100px;
    background-color: blue;
    margin-top: 10px;
}
.container {
    overflow: hidden;
}

效果:

OK,到这里你应该明白什么是 BFC 以及 BFC 的触发规则和其使用场景了。

明白了 BFC,那么其他的 IFC、GFC 和 FFC 也就大同小异了。

  • IFC(Inline formatting context):翻译成中文就是“行内格式化上下文”,也就是一块区域以行内元素的形式来格式化
  • GFC(GrideLayout formatting contexts):翻译成中文就是“网格布局格式化上下文”,将一块区域以 grid 网格的形式来格式化
  • FFC(Flex formatting contexts):翻译成中文就是“弹性格式化上下文“,将一块区域以弹性盒的形式来格式化

更多关于格式化上下文的内容,可以参阅 MDN:

BFC:

区块格式化上下文 - CSS:层叠样式表 | MDN

IFC:

行内格式化上下文(Inline formatting context) - CSS:层叠样式表 | MDN

真题解答

  • 介绍下 BFC 及其应用

参考答案:

所谓 BFC,指的是一个独立的布局环境,BFC 内部的元素布局与外部互不影响。

触发 BFC 的方式有很多,常见的有:

  • 设置浮动
  • overflow 设置为 auto、scroll、hidden
  • positon 设置为 absolute、fixed

常见的 BFC 应用有:

  • 解决浮动元素令父元素高度坍塌的问题
  • 解决非浮动元素被浮动元素覆盖问题
  • 解决外边距垂直方向重合的问题
  • 介绍下 BFC、IFC、GFC 和 FFC

参考答案:

  • BFC:块级格式上下文,指的是一个独立的布局环境,BFC 内部的元素布局与外部互不影响。
  • IFC:行内格式化上下文,将一块区域以行内元素的形式来格式化。
  • GFC:网格布局格式化上下文,将一块区域以 grid 网格的形式来格式化
  • FFC:弹性格式化上下文,将一块区域以弹性盒的形式来格式化
  • EOF
最近更新:: 2025/7/11 12:49
Contributors: AK
Prev
定位总结
Next
CSS 属性计算过程