CSS文档流相关:BFC

CSS 文档流相关:BFC

一、引言

​ display 属性接受两个值:

  • 第一个值:外部显示类型,决定了元素在所处布局扮演什么角色(block / inline)
  • 第二个值:内部显示类型,决定了元素内部的子元素按照什么方式来排列(flow / flex / grid)

如 display: block; 其实就是 display: block flow; 该元素对外以块级盒子身份参与布局,对内按照正常文档流排列子元素。

那什么是文档流呢?

二、文档流

文档流是 HTML 元素在网页中的排列方式,浏览器默认的排列方式叫做正常文档流(Normal Flow)

文档流具体的工作方式:

  • 块级盒子独占一行,垂直方向从上到下依次排列
  • 行内盒子从左到右排列,排满后自动换行

一个容器内部可能同时存在块级盒子和行内盒子,它们是如何共存的呢?

三、格式化上下文

浏览器会为这两套规则创建不同区域,他们各自在不同区域内生效,而CSS中这种有特定规则的区域,叫做格式化上下文。

如:

  • 负责块级盒子排列:块级格式化上下文(BFC)
  • 负责行内盒子排列:行内格式化上下文(IFC)

文档流就是 BFC 和 IFC 协同工作。

回到页面布局,当我们创建一个页面时,HTML 是页面的根元素,它会建立页面的第一个 BFC,还有什么会触发 BFC 的创建呢?

四、如何创建新的BFC

4.1 根元素自动创建

刚刚提到过 HTML 根元素(display: flow-root)创建了页面的第一个 BFC。

4.2 脱离文档流的情况

脱离文档流,需要独立格式化上下文的情况会创建 BFC:

  1. float 的值不是 none
  2. position: absolute 或 fixed

4.3 弹性与网格布局容器

flex/grid 容器的子元素(内部需要独立的布局环境)会创建 BFC。

4.4 overflow 属性

overflow: hidden(本职工作是控制内容溢出时的裁剪行为,创建 BFC 是副作用)。

4.5 推荐方式:display: flow-root

  • 多用 display: flow-root(display: block flow-root),元素本身是块级盒子,对外行为不变,内部显示类型是 flow-root,唯一作用是创建 BFC,没有副作用。

一个特殊的方法:将 display 改为 display: inline(可以消除外边距折叠,但也会使元素变成行内元素。)因为其全称为 display: inline flow-root,外部显示类型变为了 inline,内部创建 BFC。

五、BFC的意义

1. 解决外边距折叠

在同一个 BFC 中,相邻块级元素的垂直外边距会发生折叠。以下示例展示了问题现象及通过创建 BFC 来解决问题。

1.1 问题现象:两个相邻 div 的外边距发生折叠

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <style>
        .container {
            background-color: #f0f0f0;
            padding: 10px;
        }
        .box {
            height: 50px;
            background-color: lightblue;
            margin: 20px 0; /* 上下外边距均为 20px */
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="box">Box 1</div>
        <div class="box">Box 2</div>
    </div>
</body>
</html>

在上面的代码中,.box 的上下外边距均为 20px。按照直觉,两个盒子之间的间距应该是 20px + 20px = 40px。但由于它们处于同一个 BFC(.container 内部)中,垂直外边距发生了折叠,实际间距只有 20px。

1.2 解决方案:为其中一个盒子创建独立的 BFC

通过为其中一个 .box 添加 display: flow-root;,使其形成独立的 BFC,从而阻止外边距折叠。

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <style>
        .container {
            background-color: #f0f0f0;
            padding: 10px;
        }
        .box {
            height: 50px;
            background-color: lightblue;
            margin: 20px 0;
        }
        .bfc-box {
            display: flow-root; /* 创建独立的 BFC */
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="box">Box 1</div>
        <div class="box bfc-box">Box 2 (独立 BFC)</div>
    </div>
</body>
</html>

此时,Box 1 和 Box 2 之间的外边距不再折叠,实际间距恢复为 40px。

2. 清除浮动,解决高度塌陷

当一个父元素内部包含浮动元素时,父元素的高度可能无法被撑开(高度塌陷)。创建 BFC 可以让父元素包含其内部的浮动元素。

2.1 问题现象:父元素高度塌陷

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <style>
        .parent {
            background-color: #f0f0f0;
            border: 2px dashed #ccc;
        }
        .float-child {
            float: left;
            width: 100px;
            height: 100px;
            background-color: lightcoral;
            margin: 10px;
        }
    </style>
</head>
<body>
    <div class="parent">
        <div class="float-child">浮动子元素</div>
        <div class="float-child">浮动子元素</div>
    </div>
</body>
</html>

由于子元素浮动,父元素 .parent 的高度为 0,边框和背景色无法正常显示,这就是"高度塌陷"。

2.2 解决方案:为父元素创建 BFC

为父元素添加 display: flow-root; 或 overflow: hidden; 等属性,使其形成 BFC,从而包含内部的浮动元素。

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <style>
        .parent {
            background-color: #f0f0f0;
            border: 2px dashed #ccc;
            display: flow-root; /* 创建 BFC,清除内部浮动 */
        }
        .float-child {
            float: left;
            width: 100px;
            height: 100px;
            background-color: lightcoral;
            margin: 10px;
        }
    </style>
</head>
<body>
    <div class="parent">
        <div class="float-child">浮动子元素</div>
        <div class="float-child">浮动子元素</div>
    </div>
</body>
</html>

现在,父元素 .parent 的高度被其内部的浮动子元素撑开,背景和边框正常显示。

总结 :通过 display: flow-root 创建 BFC,既能无副作用地解决外边距折叠问题,也能有效清除浮动,是处理这类布局问题的推荐方式。

六、扩展

  • GFC:网格布局格式化上下文,形成二维表格(当 display 为 grid 时触发)
  • FFC:自适应格式上下文,形成伸缩容器(当 display 为 flex/inline-flex 时触发)
相关推荐
এ慕ོ冬℘゜12 分钟前
如何在 HTML 中嵌入音频和视频?
前端·html·音视频
变与不变8069 小时前
jQuery怎么使用
前端·javascript
神膘护体小月半9 小时前
flex 布局的 order 属性
前端·css
paopaokaka_luck9 小时前
流浪动物救助与收养系统(DeepSeek AI对话、 ECharts多维分析、救助流程衔接、领养与回访衔接、 捐赠确认与公示、志愿者协作)
java·前端·javascript·人工智能·mysql·echarts·推荐算法
仰望.9 小时前
vue 表格组件 vxe-table 树表格懒加载支持拖拽排序的详细用法
前端·javascript·vue.js·vxe-table
前端 贾公子9 小时前
vite-plugin-uni-manifest 升级指南
前端
小码哥_常9 小时前
iPhone 用户传了张 HEIC,我的前端崩了
前端
小码哥_常9 小时前
你发的原图可能暴露你家地址——聊聊图片 EXIF 隐私
前端
java1234_小锋10 小时前
【技术专题】CSS3 网页技术 - CSS3 优先级
前端·css·css3
鸿蒙开发11 小时前
共享 Schema 与 SchemaFactory
前端·后端·harmonyos