02浮动
float 诞生时只为做一件事:让文字环绕图片。
前辈们却拿它硬造了十几年的页面布局,留下著名的「高度塌陷」大坑。
本章看懂浮动的本性、踩一遍坑、学会修复,最后记住一句现代口诀:布局交给 Flex/Grid,float 只做文字环绕。
一、float 的初衷:文字环绕图片
早年报纸排版有个经典需求:图片放左边,文字顺着图片边缘绕着排,而不是整块躲到图片下面。
CSS 为此设计了 float——让元素「浮」起来靠边站,周围的行内内容自动让位环绕。
float: left 改成 right,图片立刻靠右把文字让到左边left(靠左浮)、right(靠右浮)、
none(默认,不浮动)。设置后元素会向指定方向移动,直到碰到容器边缘或另一个浮动元素为止。二、float 的三个特性
浮动元素有三条「本性」,后面所有的坑都源于它们:
- ① 脱离文档流:后面的块级盒子当它不存在,会顶上来和它重叠;
- ② 块级收缩包裹:浮动的块级元素不再撑满父级,宽度收缩到刚好包住内容;
- ③ 行内内容让位:虽然脱离文档流,但周围的行内内容(文字、行内元素)会绕开它排——这正是环绕效果的来源。
| 特性 | 具体表现 | 这解释了设么坑 |
|---|---|---|
| ① 脱离文档流 | 后面的块级盒子顶上来与它重叠 | 重叠、错位 |
| ② 收缩包裹 | 块级浮动元素不再撑满父级,宽随内容 | 宽度突然变小 |
| ③ 行内让位 | 文字 / 行内元素绕开它排 | 图文混排的正常来源 |
.ghost 改成 float: right,重叠和绕行立刻换边三、高度塌陷:浮动最经典的坑
把特性①和②组合起来,就得到浮动时代最著名的 bug:高度塌陷。 父元素不写高度,指望被子元素撑开;可子元素全部浮动了,父元素「看不见」它们—— 于是父元素高度变成 0,边框塌成一条线,后面的兄弟元素整体上移,与浮动的子元素叠在一起。
.fl-col-parent 上补一行 height: 90px,父级又能包住盒子(但那是硬撑,不是治本)四、clear:清除浮动
修复塌陷的第一代方案是 clear 属性。它的含义是:
我这个元素的某一侧不允许出现浮动元素,有的话我就往下挪,直到躲开为止。
在浮动子元素的后面放一个空的块级元素并设置 clear: both,它会被「压」到所有浮动元素的下方,
于是父元素为了包住它,高度就被重新撑开了。
| 取值 | 含义 | 什么时候用 |
|---|---|---|
| none | 默认,不清除 | — |
| left | 左侧不允许有左浮动元素 | 只想躲开左浮动的场景 |
| right | 右侧不允许有右浮动元素 | 只想躲开右浮动的场景 |
| both | 左右两侧都不允许有浮动元素 | 无脑选它,最常用 |
.fix 的 clear 改成 none,父级瞬间又塌了——空元素是撑高的关键clear 只对块级元素生效,且清除的是「它自己」与浮动的关系,
并不会真的把浮动元素拉回文档流——它是绕道,不是根治。五、clearfix:万能修复方案
空元素方案要污染 HTML,于是前辈们发明了更优雅的clearfix:
用 ::after 伪元素在父元素内容的最末尾「凭空造出」那个带 clear: both 的空盒子。
HTML 一个字都不用改,往父元素身上挂一个 clearfix 类就完事。
.fl-clearfix::after 里的 display: table 删掉,看是否还能撑起父级(display: table 是兼容性关键)display: flow-root(让容器自己形成格式化上下文,天然包住浮动)一行顶 clearfix 三行;
不过既然新项目已经不用浮动做布局,这段代码的主要价值是——看懂老代码。六、历史遗产:float 三栏布局
在 Flex 出现之前,页面骨架就是这么硬凑的:左列左浮动、右列右浮动、中间列用 margin 让位。 注意 HTML 顺序:中间列必须写在最后,这是浮动布局最别扭的约束之一。
.fl-holy .middle 的 margin 为 0,中间栏立刻钻到左右两栏下面
这套写法的痛点一眼可见:HTML 顺序与视觉顺序不一致、必须手动清除浮动、
三栏无法天然等高(中间高了,两侧不会跟着长)。
Flex 用三行代码解决了全部问题(display: flex + 两侧定宽 + 中间 flex: 1),
这正是它彻底取代浮动布局的原因,第 05 课详见。
七、本章小结
float的本职工作是文字环绕:left / right / none。- 浮动三特性:脱离文档流(块级盒子当它不存在)、收缩包裹(宽度包住内容)、行内让位(文字绕行)。
- 子级全浮,父级塌陷:父元素高度变 0,边框塌成线,兄弟元素上移重叠。
- 修复方案:空元素
clear: both(污染 HTML)→.clearfix::after伪元素(万能)→ 现代display: flow-root。 - float 三栏布局是历史遗产,已被 Flex 取代——但老项目里遍地都是,必须看得懂。
- 现代开发口诀:布局交给 Flex/Grid,float 只做文字环绕。
float: right,观察它们排列顺序的变化(浮动会按 HTML 顺序依次从右往左靠)。