CSS清除浮动

概述

浮动的元素在脱离了普通流之后,会按照浮动流的行为进行排列,而不再受父级元素中容器管理,也就是说浮动元素无视父级元素的排布关系,会自行在浮动流中进行排列,这种现象也称为浮动塌陷

问题的出现

考虑如下代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<body>
<div>
<ol>
<li>菜单一</li>
<li>菜单一</li>
<li>菜单一</li>
<li>菜单一</li>
</ol>
</div>
<div>
<ol>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
</ol>
</div>
</body>
1
2
3
4
5
6
li {
display: inline-block;
background-color: yellow;
margin: 5px 5px;
float: left;
}

按照常理,我们会理解为如下效果。

可是实际的效果却是。

问题是因为第二个菜单中的列表项标签(li标签)已经脱离了普通流,不再考虑普通流中的父级元素了,这就是浮动塌陷。

解决方案一:为父元素设置高度

我们知道,浮动的元素的上边会和普通流中的上一个元素的底边对齐,但是这个场景很明显第一个div是第二个列表中浮动的列表项标签在普通流中的上一个元素。因此明显应该与其底边对齐,但是问题就在第一个div是没有高度的。

这个时候我们可以为其设置一个高度,具体如下。

1
2
3
4
5
6
/*div {
height: 40px;
}*/
ol {
height: 40px;
}

为div或者ol设置一个高度都行,因为ol也会撑开div的高度。

这是最直观的解决方案,但缺点在于开发者必须手动设置一个高度,需要手动计算,且由于这个高度可能会影响之后的布局。

解决方案二:overflow属性

overflow属性有个特点,就是一旦设置值为hidden,该元素就会有高度了,所以这是解决浮动塌陷的一个偏方。

1
2
3
4
5
6
/*div {
overflow: hidden;
}*/
ol {
overflow: hidden;
}

同样,对于上面的HTML结构,设置在ol上或者div上都是有用的。但是这种方式的缺点在于,如果我们的div有溢出而我们又恰好需要让溢出的方式展现出来呢?那这种情况下我们就不能将overflow设置成hidden。

解决方案三:clear属性

CSS中有一个专门用于清除浮动的属性,clear属性。

1
2
3
div {
clear: both;
}

clear属性可以设置为left,right,或者both。设置之后该元素的指定方向(左、右或者两边)就不能有浮动元素了,如果有浮动元素,则设置了clear属性的元素就会自动挪开到下一行中。

注意:clear属性只会移动自身元素,并不是移动浮动元素。

解决方案四:隔墙法

使用clear属性这种方法,会使我们的元素的margin属性失效,因此,这种方法也有一定的局限性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<body>
<div>
<ol>
<li>菜单一</li>
<li>菜单一</li>
<li>菜单一</li>
<li>菜单一</li>
</ol>
</div>
<div style="clear: both"></div>
<div>
<ol>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
</ol>
</div>
</body>

隔墙法是在两个div元素中添加一个设置了clear属性的没有高度的元素。

解决方案五:内墙法

内墙法的思想就是把隔墙法的“墙”放到上一个div中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<body>
<div>
<ol>
<li>菜单一</li>
<li>菜单一</li>
<li>菜单一</li>
<li>菜单一</li>
<div style="clear: both"></div>
</ol>
</div>
<div>
<ol>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
<li>菜单二</li>
</ol>
</div>
</body>

内墙法可以不用在两个div之间添加清除浮动的附加元素。

解决方案六:伪元素内墙法

总地来讲,外墙法内墙法都能有效解决清除浮动的问题,但是现在企业中最流行的方法是内墙法的改进法,使用伪元素的内墙法。

1
2
3
4
5
ol:after {
content: '';
display: block;
clear: both;
}

这种方法的有点在于HTML不需要做任何修改,不需要添加任何额外的HTML标签就能完美解决清除浮动的问题,这也是目前企业中最流行的解决方法。

总结

实际上方案四五六都能比较好地解决清除浮动的问题,笔者倾向于使用伪元素内墙法,读者可以依据实际情况作出选择。