技术备忘 CSS前端

⚠️ 本文写于 2012 年,当时 Flexbox 和 Grid 还未普及。现代布局推荐使用 Flexbox 或 Grid。

做网页布局的时候经常会用到浮动(float),但是浮动也会带来一些问题,比如父元素高度塌陷。

今天整理一下 CSS 浮动的原理和几种清除浮动的方法。

什么是浮动

CSS 的 float 属性可以让元素向左或向右浮动,直到它的边缘碰到包含框或另一个浮动框的边缘。

css
.left {
float: left;
}
.right {
float: right;
}

浮动最初是用来实现文字环绕图片的效果:

html
<img src="photo.jpg" style="float: left; margin: 10px;">
<p>这是一段文字,会环绕在图片周围...</p>

但后来被大量用于页面布局,比如实现多栏布局:

html
<div class="container">
<div class="left">左侧栏</div>
<div class="right">右侧栏</div>
<div class="main">主内容</div>
</div>

浮动带来的问题

问题 1:父元素高度塌陷

当子元素全部浮动时,父元素会失去高度,变成 0:

html
<div class="parent">
<div class="child" style="float: left;">浮动元素</div>
<div class="child" style="float: left;">浮动元素</div>
</div>

此时 .parent 的高度为 0,因为浮动元素脱离了文档流。

问题 2:后续元素布局错乱

浮动元素后面的元素会围绕浮动元素排列,导致布局混乱:

html
<div class="float" style="float: left; width: 100px; height: 100px;">浮动</div>
<div class="normal">这段文字会环绕在浮动元素周围</div>

清除浮动的方法

方法一:在浮动元素后添加空 div

这是最简单粗暴的方法:

html
<div class="parent">
<div class="child" style="float: left;">浮动元素</div>
<div class="child" style="float: left;">浮动元素</div>
<div style="clear: both;"></div>
</div>

缺点:增加了无意义的 HTML 标签,不推荐。

方法二:父元素设置 overflow

给父元素设置 overflow: hiddenoverflow: auto

css
.parent {
overflow: hidden;
}

原理:触发 BFC(Block Formatting Context,块级格式化上下文)。

缺点:如果子元素有定位或阴影,可能会被裁剪掉。

方法三:父元素也设置浮动

css
.parent {
float: left;
}

缺点:会影响后续元素布局,父元素也脱离了文档流。

方法四:使用 :after 伪元素(推荐)

这是目前最常用的方法:

css
.clearfix:after {
content: "";
display: block;
clear: both;
}
.clearfix {
*zoom: 1; /* IE6/7 兼容 */
}

使用方法:

html
<div class="parent clearfix">
<div class="child" style="float: left;">浮动元素</div>
<div class="child" style="float: left;">浮动元素</div>
</div>

优点

  • 不增加额外的 HTML 标签
  • 兼容性好
  • 可复用

这是我目前最常用的方法,基本能解决所有浮动问题。

方法五:父元素设置固定高度

css
.parent {
height: 200px;
}

缺点:不灵活,内容变化时需要修改高度,不推荐。

clear 属性

clear 属性用于清除浮动,它有以下几个值:

说明
left清除左浮动
right清除右浮动
both清除左右浮动
none不清除(默认值)
css
.clear {
clear: both;
}

实际应用示例

两栏布局

html
<div class="container clearfix">
<div class="sidebar">侧边栏</div>
<div class="content">主内容</div>
</div>
css
.sidebar {
float: left;
width: 200px;
}
.content {
float: right;
width: 780px;
}
.clearfix:after {
content: "";
display: block;
clear: both;
}

三栏布局

html
<div class="container clearfix">
<div class="left">左栏</div>
<div class="center">中间</div>
<div class="right">右栏</div>
</div>
css
.left {
float: left;
width: 200px;
}
.center {
float: left;
width: 580px;
}
.right {
float: right;
width: 200px;
}

浏览器兼容性

IE6/7 的问题

IE6/7 不支持 :after 伪元素,需要使用 zoom: 1 触发 hasLayout:

css
.clearfix:after {
content: "";
display: block;
clear: both;
}
.clearfix {
*zoom: 1; /* 仅 IE6/7 识别 */
}

更完善的 clearfix

网上有个更完善的版本,兼容性更好:

css
.clearfix:before,
.clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix {
*zoom: 1;
}

总结

浮动是 CSS 布局的重要方式,但也容易出问题。记住几点:

  1. 浮动元素脱离文档流,父元素高度会塌陷
  2. 清除浮动的最佳方法是使用 :after 伪元素
  3. 不要滥用浮动,能用其他方法就用其他方法
  4. 注意浏览器兼容性,特别是 IE6/7

把 clearfix 的代码保存下来,以后每个项目都能用。


参考资料