在网页排版中,块级元素如div默认会占满一行从上往下堆叠。如果希望几个模块横向并排,比如做两栏布局或图片环绕文字,就要用到CSS的浮动机制。浮动通过float属性让元素脱离标准文档流,并向指定方向平移,直到外边缘抵住包含块或另一个浮动元素为止。

一、float属性基础设置
float是CSS中控制元素浮动方向的核心属性,它接受几个常用值:left让元素向左浮动,right向右浮动,none恢复不浮动(默认值),inherit表示继承父级浮动设定。当一个元素设置浮动后,它会被移出普通流,但依然处于当前行的空间内,后面的非浮动块级元素会无视它的占位,直接从它原来的起始位置往下排,不过行内内容如文字会绕开浮动框。
下面是一段最基础的浮动设置代码,我们让两个色块横向排列:
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px;
height: 100px;
border: 1px solid #333;
}
.left {
float: left;
background: #cde;
}
.right {
float: left;
background: #ecd;
}
</style>
</head>
<body>
<div class="box left">左浮块</div>
<div class="box right">右浮块</div>
</body>
</html>
上述代码中,两个div都设了float:left,因此它们会从左向右依次紧贴排列,而不是上下换行。如果去掉浮动,它们会因块级特性各占一行。需要注意的是,浮动元素会生成块级框,即便原先是行内元素,设置浮动后也能设宽高。
1.1 浮动方向与边界
浮动方向决定了元素平移的参照。向左浮动时,元素左边缘尽量靠左,碰到父容器content区左内边界或前一个左浮动元素的右外边界便停下;向右浮动同理。多个同方向浮动元素会像队列一样顺序排列,空间不够时自动换到下一行,这点和inline-block有相似之处,但浮动脱离文档流,不会留下空白间隙。
利用这一特性,我们可以轻松实现导航菜单横排。不过若父容器没设宽,浮动子元素总宽度超出视口,就会出现折行,此时要检查盒模型计算是否包含了padding和border。
二、浮动带来的高度塌陷问题
由于浮动元素脱离普通流,其父容器在普通流中计算高度时不会把浮动子元素的高度算进去。如果父容器没有其他非浮动内容撑开,它的高度就会变成0,这就是所谓的高度塌陷。塌陷会导致父容器背景、边框无法正常包裹子元素,后续兄弟元素也会上浮到错误位置,版面错乱。
看下面这个例子,父div包了两个浮动子div,但自身高度没被撑开:
<div class="wrap" style="border:2px solid red;"> <div style="float:left;width:80px;height:80px;background:gray;"></div> <div style="float:left;width:80px;height:80px;background:blue;"></div> </div> <p>我是后面的段落,会跑到红色边框里面去。</p>
运行后红色边框高度几乎为0,段落文字紧贴在浮动块右侧甚至叠入边框区。这种问题在动态内容页面尤其隐蔽,常让初学者误以为是margin或定位出错。
2.1 为什么普通流不计算浮动高度
CSS规范将浮动定义为“不完全脱离文档流”,它脱离了普通块级格式化上下文,但仍在同一个块格式化上下文(BFC)内对行盒产生影响。父容器若未创建新BFC,其内部高度由普通流中的盒子决定,浮动盒不参与此高度贡献,于是出现塌陷。理解这点才能明白后续清除手段的本质。
某些场景下我们恰恰利用塌陷做图文混排,但作为布局容器时必须处理它,否则响应式缩放时错位会被放大。
三、清除浮动的常用方案
清除浮动并不是删掉float,而是让后续元素或父容器正确感知浮动结束。业界总结了几种稳定做法,各有适用面。
3.1 额外空标签法
在浮动元素末尾加一个空块级标签,设clear:both。clear属性规定元素哪侧不允许有浮动,both即左右都清。此法简单直观,但凭空多了无语义标签,不利于维护和SEO。
<div class="wrap"> <div style="float:left;">浮块</div> <div style="clear:both;"></div> </div>
优点是兼容性极佳,老旧浏览器也支持;缺点是若页面大量使用会让DOM变脏。现代开发更推荐伪元素方案替代。
3.2 伪元素after清除
给父容器加一个类,用::after生成内容并清除浮动,这是目前最主流做法。伪元素在父容器内容末尾插入一个不可见块盒,设clear:both,同时需display:block才能生效。
.clearfix::after {
content: "";
display: block;
clear: both;
}
HTML里父容器写上class="clearfix"即可。这种方式不污染结构,复用率高。要注意若父容器本身overflow为visible以外的值也可能触发BFC,但伪元素法更可控,不会裁剪溢出内容。
3.3 overflow触发BFC
给父容器设overflow:hidden或auto,能使其建立新的块格式化上下文,内部浮动参与高度计算,塌陷消失。代码量最少,但hidden会裁掉超出部分,auto可能出滚动条,按场景选用。
.wrap {
overflow: hidden;
}
该方案对IE6需配合zoom:1触发hasLayout。现代浏览器可直接用。它适合父容器本就需要隐藏溢出的模块,否则优先clearfix。
四、浮动与inline-block的对比
除了浮动,用display:inline-block也能让元素横排。区别在于inline-block留在普通流,元素间有空白符间隙,且基线对齐可能引发底部错位;浮动脱离流,无间隙但需处理塌陷。表格类数据用inline-block更省心,复杂栏用浮动加清除更灵活。
| 特性 | float | inline-block |
|---|---|---|
| 是否脱离文档流 | 是 | 否 |
| 父容器高度塌陷 | 会 | 不会 |
| 元素间空格 | 无 | 有 |
实际项目中,CSS Flexbox与Grid已能替代多数浮动布局,但维护老代码或做文字环绕时,掌握float设置与清除仍是前端基本功。建议新布局用Flex,旧页面理解浮动原理便于排错。