我在做页面布局的时候,多多少少总会受到来自浮动的困扰,因此专门通过实践来总结一下浮动与清除浮动。
首先总结几个基础的概念:
浮动:设置浮动的元素会脱离文档流,不会影响块元素的布局,但是会影响内联元素的排列[通常是文本];
文档流:在文档流中,块元素会单个元素独占一行
接下来我们通过实际演示来看看关于浮动的那些事儿。
下面是5个div块元素在文档流中一次排列
我们知道浮动元素有几个规律
- 如果浮动元素的上一个元素也是浮动,那么该元素会与上一个元素排列在同一行,如果行宽不够,后面的元素会被挤到下一行
- 如果浮动元素的上一个元素不是浮动,那么该元素仍然处于上一个元素的下方,根据浮动设定在左或者在右,而其本身也脱离文档流。后边的元素会自动往上移动到上一个文档流块元素下方为止
根据上面的规则,我们做一些改动来验证一下
给2添加左浮动,给3添加右浮动
首先1没有浮动,所以2在1的下一行,而3的上一个元素2是有浮动的,所以3和2在同一行,2和3因为有了浮动,所以脱离了文档流,他们后面的元素4就自动往上移动,处于1的下方
给元素2添加左浮动
因为它的上一个元素1没有浮动,所以排列在1的下方,不和1同一行。而元素2同时脱离了普通流,因此后边的元素会顶替上来
因此,浮动元素的位置是根据他的上一个元素来确定的[以及浮动位置来确定]
清除浮动
可能浮动会比较好理解一点,而不少人会对清除浮动有一些误解。
- 清除浮动并不是说让浮动元素回到文档流
- 清除浮动只会改变改元素自身的位置,并且只针对排在该元素前面的元素。目的是让自己的左边或者右边没有浮动元素
例子1
给2添加左浮动,给3添加右浮动,之后给3添加清除左边的浮动。
因为2是3的上一个元素,所以给3清除浮动,只有2才能影响他的位置,而2在3的左边,因此只有给3添加清除左浮动才有效果,清除左边浮动的意思,就是让2不在3的左边,所以3会改变自己的位置,移动到2的下一行,但是右浮动的效果任然在,所以在下一行的右侧
再给5添加删除右浮动效果,因为5的右边有一个浮动元素是3,而3是5前面的元素,因此5会改变位置,让自己左右没有浮动元素
例子2
给1,2,3,4添加左浮动
然后给3添加清除左浮动的效果。如果直接给3清除右浮动,将没有任何变化,因为3右边的浮动效果是4,而4处于3的后边,不会影响3的位置
关于高度坍塌
当没有指定高度的父元素中的子元素全部都浮动时,父元素中内部高度因为是普通流中的块元素撑起来的,所以这个时候父元素的高度会变成0.或者会有部分浮动元素的位置会超出父元素的高度之外。这种现象,叫做高度坍塌。
如下图,给元素设置左浮动。设置了边框的父元素因为没有高度所以上下边框重合,看上去就像一条线
解决方法:使用:after伪元素
<!-- 浮动 清除浮动 高度坍塌 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>高度坍塌</title>
<style>
.div1 {
border: 1px solid #ccc;
}
.div1:after {
content: ‘.‘;
display: block;
height: 0;
visibility: hidden;
clear: both;
}
.div2 {
width: 100px;
height: 100px;
margin: 5px;
background-color: orange;
float: left;
}
</style>
<!--[if IE]>
<style>
.div1 {
zoom:1;/*触发hasLayout*/
display:block;
}
</style>
<![end]-->
</head>
<body>
<div class="div1">
<div class="div2"></div>
</div>
</body>
</html>
after的原理是在div1的子元素最末尾添加一个元素,如果该元素能够位于div2的后面,并且没有浮动,那么父元素div1的高度就会重新获取。因此使用了上方的解决方案
因此,闭合浮动之后,一切恢复正常
这就是通过在子元素末尾添加伪元素来解决高度坍塌问题的解决方案。