第16篇:文档流与浮动
文档流是 CSS 布局的根基。理解块级格式上下文(BFC)、浮动清除以及文档流的本质,是掌握复杂布局的前提。本篇将从浏览器如何排列元素说起,深入讲解正常流、浮动、BFC 等核心概念。
学习目标
- 理解什么是正常文档流(Normal Flow)
- 掌握 BFC(块级格式上下文)的概念与触发条件
- 理解浮动(float)的设计初衷与使用场景
- 掌握清除浮动的多种方法及最佳实践
- 理解 IFC(行内格式上下文)的基本概念
- 学会用浮动实现简单的多栏布局
核心知识点
一、什么是文档流?
文档流(Document Flow),也称为正常流(Normal Flow),是浏览器默认的排版方式。元素按照 HTML 中出现的顺序,从上到下、从左到右依次排列。
正常流中的两种排列方式
块级格式上下文(Block Formatting Context, BFC):
- 块级元素独占一行,垂直排列
- 每个块级元素的左边缘紧贴包含块的左边缘
/* 块级元素在正常流中的行为 */
div, p, h1, section {
display: block;
/* 默认宽度 = 父容器宽度 */
/* 默认高度 = 内容高度 */
}
行内格式上下文(Inline Formatting Context, IFC):
- 行内元素在水平方向依次排列
- 当一行排不下时,自动换行
/* 行内元素在正常流中的行为 */
span, a, strong, em {
display: inline;
/* 宽度由内容决定 */
/* 高度由 line-height 决定 */
}
二、脱离文档流的方式
元素一旦脱离文档流,就不再参与正常流的排列。
| 浮动 | float: left/right | 元素向左/右浮动 |
| 绝对定位 | position: absolute | 相对于最近的定位祖先 |
| 固定定位 | position: fixed | 相对于视口 |
| 弹性布局 | display: flex | 创建 Flex 上下文 |
| 网格布局 | display: grid | 创建 Grid 上下文 |
三、浮动(float)详解
浮动的设计初衷
/* 最初设计目的:让文字环绕图片 */
.article img {
float: left; /* 图片向左浮动 */
margin: 0 16px 16px 0; /* 文字与图片间距 */
}
浮动元素会:
float 取值
.none { float: none; } /* 默认值,不浮动 */
.left { float: left; } /* 向左浮动 */
.right { float: right; } /* 向右浮动 */
文字环绕效果
<div class="article">
<img src="photo.jpg" class="float-left" alt="">
<p>这是一段很长的文字…</p>
</div>
.float-left {
float: left;
width: 200px;
height: 150px;
margin: 0 16px 8px 0;
}
.article p {
/* 文字会自动环绕图片 */
}
四、浮动的副作用:高度塌陷
当容器内的子元素全部浮动时,容器会失去高度——因为浮动元素脱离了文档流。
<div class="parent">
<div class="float-child">浮动元素 1</div>
<div class="float-child">浮动元素 2</div>
</div>
.float-child {
float: left;
width: 100px;
height: 100px;
background: #4a90d9;
}
.parent {
background: #f0f0f0;
/* ❌ 父元素高度为 0! */
}
五、清除浮动的六种方法
方法 1:额外空元素 + clear
<div class="parent">
<div class="float-child"></div>
<div class="float-child"></div>
<div style="clear: both;"></div> <!– 额外元素 –>
</div>
❌ 不推荐:增加无意义 HTML
方法 2:伪元素清除(推荐)
.clearfix::after {
content: "";
display: block; /* 或 table */
clear: both;
}
<div class="parent clearfix">
<div class="float-child"></div>
<div class="float-child"></div>
</div>
✅ 最常用:不增加额外 HTML,兼容性好
方法 3:父元素 overflow
.parent {
overflow: hidden; /* 或 auto */
}
⚠️ 副作用:可能会裁剪内容或显示滚动条
方法 4:父元素也浮动
.parent {
float: left;
}
❌ 不推荐:影响父元素自身的布局
方法 5:父元素 display: flow-root(现代)
.parent {
display: flow-root; /* 创建 BFC,无副作用 */
}
✅ 推荐:语义清晰,无副作用,但 IE 不支持
方法 6:父元素 display: flex/grid
.parent {
display: flex;
/* 或 display: grid; */
}
💡 Flexbox/Grid 容器自动包裹浮动子元素
清除浮动方法总结:
| 空元素 + clear | 简单直观 | 增加无意义 HTML |
| 伪元素 clearfix | 纯 CSS,无额外标签 | 需要记住代码片段 |
| overflow | 简单 | 可能裁剪内容 |
| flow-root | 语义正确,无副作用 | IE 不支持 |
| flex/grid | 现代布局 | 改变布局方式 |
六、BFC(块级格式上下文)
什么是 BFC?
BFC 是 CSS 中一个独立的渲染区域,内部的元素布局不会影响外部,外部的也不会影响内部。
BFC 的创建条件
/* 以下任意一种都会创建 BFC */
.bfc-1 { overflow: hidden; } /* 最常见 */
.bfc-2 { overflow: auto; }
.bfc-3 { display: flow-root; } /* 最推荐(现代浏览器) */
.bfc-4 { display: inline-block; }
.bfc-5 { float: left; } /* 浮动元素自身 */
.bfc-6 { position: absolute; } /* 绝对/固定定位 */
.bfc-7 { position: fixed; }
BFC 的特性
/* 特性 1:BFC 内部浮动元素会被计算高度 */
.parent {
overflow: hidden; /* 创建 BFC */
}
.parent .float-child {
float: left;
}
/* 父元素会自动包裹浮动子元素 */
/* 特性 2:BFC 区域不会与浮动元素重叠 */
.main {
float: left;
width: 70%;
}
.sidebar {
overflow: hidden; /* 创建 BFC,自动避开浮动元素 */
}
/* 特性 3:BFC 内部 margin 不会与外部折叠 */
.bfc-container {
overflow: hidden; /* 创建 BFC */
}
.bfc-container p {
margin: 20px 0; /* margin 不会穿透到外部折叠 */
}
七、浮动布局实战:多栏布局
经典两栏布局
<div class="two-column clearfix">
<div class="main">主内容区</div>
<div class="sidebar">侧边栏</div>
</div>
.two-column {
max-width: 900px;
margin: 0 auto;
}
.main {
float: left;
width: 70%;
padding: 20px;
background: #f9fafb;
}
.sidebar {
float: left;
width: 30%;
padding: 20px;
background: #e3f2fd;
}
.clearfix::after {
content: "";
display: block;
clear: both;
}
三栏布局(双飞翼/圣杯布局的简化版)
.three-column .col {
float: left;
width: 33.33%;
padding: 20px;
box-sizing: border-box;
}
动手练习
练习 1:文字环绕图片
实现一个图文混排效果:
- 图片向左浮动
- 文字环绕图片右侧和底部
- 图片与文字之间有适当间距
练习 2:清除浮动对比
创建包含浮动子元素的父容器:
- 不使用清除浮动,观察高度塌陷
- 分别用 overflow:hidden、伪元素、flow-root 三种方法清除
- 对比效果差异
练习 3:浮动多栏布局
用 float 实现一个三栏布局:
- 三栏等宽排列
- 每栏之间有间距
- 父容器正确包裹所有子元素
常见误区 ⚠️
| “浮动元素完全脱离文档流” | 浮动是"半脱离"——块级元素当它不存在,但行内内容会环绕它 |
| “clear: both 只能用在空 div 上” | 可以用在任何元素上,包括伪元素 |
| “overflow: hidden 是清除浮动的最佳方法” | 它可能裁剪内容,伪元素 clearfix 或 flow-root 更推荐 |
| “所有块级元素都能创建 BFC” | 需要特定条件(如 overflow、float、position 等) |
| “flex/grid 不需要清除浮动” | 正确!它们本身就是独立的格式上下文 |
| “float 适合所有布局场景” | 现代布局应优先使用 flexbox/grid,float 主要用于文字环绕 |
| “BFC 就是清除浮动” | BFC 远不止清除浮动,它还能阻止 margin 折叠、避免浮动重叠 |
| “display: flow-root 兼容性不好” | IE 不支持,但所有现代浏览器都支持,是创建 BFC 的最佳方式 |
速查卡片 📋
脱离文档流的方式
float: left/right;
position: absolute/fixed;
display: flex/grid;
清除浮动(clearfix)
.clearfix::after {
content: "";
display: block;
clear: both;
}
BFC 创建方式
overflow: hidden;
overflow: auto;
display: flow-root; /* 推荐 */
display: inline-block;
float: left;
position: absolute/fixed;
浮动多栏布局
.col {
float: left;
width: 33.33%;
box-sizing: border-box;
}
扩展阅读
- MDN: 浮动
- MDN: 块级格式上下文
- MDN: clear
- CSS-Tricks: All About Floats(英文)
📌 配套代码:
- CODE/16/float-demo.html — 浮动与文字环绕演示
- CODE/16/clearfix-bfc.html — 清除浮动与 BFC 实战
🎉 下一步:进入 第17篇:溢出处理与文本截断,学习 overflow 和文本截断的完整方案。

