第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;}/* 向右浮动 */文字环绕效果
<divclass="article"><imgsrc="photo.jpg"class="float-left"alt=""><p>这是一段很长的文字...</p></div>.float-left{float:left;width:200px;height:150px;margin:0 16px 8px 0;}.article p{/* 文字会自动环绕图片 */}四、浮动的副作用:高度塌陷
当容器内的子元素全部浮动时,容器会失去高度——因为浮动元素脱离了文档流。
<divclass="parent"><divclass="float-child">浮动元素 1</div><divclass="float-child">浮动元素 2</div></div>.float-child{float:left;width:100px;height:100px;background:#4a90d9;}.parent{background:#f0f0f0;/* ❌ 父元素高度为 0! */}五、清除浮动的六种方法
方法 1:额外空元素 + clear
<divclass="parent"><divclass="float-child"></div><divclass="float-child"></div><divstyle="clear:both;"></div><!-- 额外元素 --></div>❌ 不推荐:增加无意义 HTML
方法 2:伪元素清除(推荐)
.clearfix::after{content:"";display:block;/* 或 table */clear:both;}<divclass="parent clearfix"><divclass="float-child"></div><divclass="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 不会穿透到外部折叠 */}七、浮动布局实战:多栏布局
经典两栏布局
<divclass="two-column clearfix"><divclass="main">主内容区</div><divclass="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 和文本截断的完整方案。