一、浮动的本质
浮动的核心只有一句话:浮动元素会脱离标准文档流向左/向右浮动,直到碰到父元素或者另一个浮动元素。
二、浮动的特征
2.1浮动会脱离文档
也就是说浮动会脱离原来文档流所在的层级,进入更高的层级。它在更高的层级上会忽略标准文档流中的元素,向左向右直到碰到父元素或者另一个浮动元素。同时在标准文档流中,剩余的元素也会当做该浮动元素不存在。
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.box-wrapper {
border: 5px solid red;
}
.box1 {
float: right;
width: 100px;
height: 100px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box2 {
float: right;
width: 100px;
height: 100px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box3 {
/*float: right;*/
width: 100px;
height: 100px;
margin: 20px;
background-color: green;
font-size: 80px;
}
</style>
<link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
<div class="box1">1</div>
<div class="box2">2</div>
<div class="box3">3</div>
<!--<div style="clear: left"></div>-->
</div>
</body>
</html>
运行结果:
分析:在以上示例中,第一个和第二个元素向右浮动,第三个元素未设置浮动。这时候第一个元素碰到边框元素停下,第二个元素碰到第一个元素停下,第三个元素仍然在标准文档流中,并且认为第一个第二个元素的位置为空。
2.2浮动可以内联排列
示例代码如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.box-wrapper {
border: 5px solid red;
}
.box1 {
float: right;
width: 100px;
height: 200px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box2 {
float: right;
width: 100px;
height: 100px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box3 {
float: right;
width: 100px;
height: 100px;
margin: 20px;
background-color: green;
font-size: 80px;
}
</style>
<link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
<div class="box1">1</div>
<div class="box2">2</div>
<div class="box3">3</div>
<!--<div style="clear: left"></div>-->
</div>
</body>
</html>
运行结果如下:
分析:当放大或者缩小浏览器的框会有不同的显示效果。这是因为浮动会向左向右浮动,直到碰到另外一个浮动元素为止。这是浮动可以内联排列的特征。这个特征介于inline和block之间,类似于inline-block的效果。
2.3浮动会导致父元素坍塌
出现这个情况的原因是浮动元素会脱离标准文档流,并不占据标准文档流的位置,而标准文档流中的其他元素会占据浮动元素的位置,当没有其他元素的时候,父元素就不能被撑开,所以就没有了高度。
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.box-wrapper {
border: 5px solid red;
}
.box1 {
float: right;
width: 100px;
height: 100px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box2 {
float: right;
width: 100px;
height: 100px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box3 {
float: right;
width: 100px;
height: 100px;
margin: 20px;
background-color: green;
font-size: 80px;
}
</style>
<link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
<div class="box1">1</div>
<div class="box2">2</div>
<div class="box3">3</div>
<!--<div style="clear: left"></div>-->
</div>
</body>
</html>
运行结果:
分析:从运行结果可以看出,父元素坍塌了。
三、深入理解clear属性
clear属性不允许被清除浮动的元素所在行的左边/右边有浮动元素(从浏览器界面上来看),底层原理是在被清除浮动的元素上边或者下边添加足够的清除空间。
同时,我们是在通过在别的元素上清除浮动来实现撑开高度的,而不是在浮动元素上。
3.1在浮动元素上加上清除浮动的属性
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.box-wrapper {
border: 5px solid red;
}
.box1 {
float: right;
width: 100px;
height: 200px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box2 {
float: right;
width: 100px;
height: 100px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box3 {
float: right;
width: 100px;
height: 100px;
margin: 20px;
background-color: green;
font-size: 80px;
}
</style>
<link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
<div class="box1">1</div>
<div class="box2">2</div>
<div class="box3" style="clear: both">3</div>
<!--<div style="clear: both"></div>-->
</div>
</body>
</html>
运行结果:
结果分析:首先,可以观察到父元素还是坍塌了;其次,在浏览器的显示界面上,左边明明还有很大的空间,但是3号元素并没有靠着2号元素去排列,而是排列在了下面。导致这样的结果出现的原因是:虽然在3号标签上加了清除浮动,但是3号元素同时设置了浮动属性,导致了这个清除浮动效果在浮动元素的那个层级生生效了,并没有在标准文档流里面生效。
3.2综合示例
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.box-wrapper {
border: 5px solid red;
}
.box1 {
float: right;
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box2 {
float: right;
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box3 {
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
</style>
<link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
<div class="box3">1</div>
<div class="box1">2</div>
<div class="box1">3</div>
<div class="box2" style="clear: both">4</div>
<div class="box3">5</div>
<div class="box3" style="clear: both">6</div>
</div>
</body>
</html>
运行结果:
结果分析:1号框是正常的,没有浮动;2号框设置向右浮动,但是它并不跟1号框同行,相当于在2号框的上外边画一条横线,跟上面隔离开,然后在剩下的界面上开始浮动;3号框设置向右浮动,就是一个普通的浮动;4号框设置向右浮动和清除浮动,不跟2、3号同行,相当于在上面画一条线,从下面开始浮动;5号框是一个普通框,可以看到它补充了2、3、4号框的位置;6号框设置了清除浮动,可以看到它相当于在4号框下面画了一条线,然后补充进在标准文档流的位置。同时,可以观察到父元素的框并没有垮掉,这是因为有最后的1、5、6号元素。当把6号框注释掉的时候,父框的高度只到5号框那个地方。当注释掉5、6号框的时候,父框高度只到1号框那个地方,当这三个框都注释掉的时候,父元素坍塌了。
上面这个示例包含了四种情况:1、什么都不设置(1、5);2、只设置浮动(2、3);3、只设置清除浮动(6);4、同时设置浮动和清除浮动(4)。
四、解决父级边框塌陷的方法
- 浮动元素后面加空div
- 设置父元素的高度
- 父级添加overflow属性
- 父级添加伪类after
4.1在标准文档流中的剩余元素上清除浮动实现撑开高度
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.father {
border: 5px solid red;
}
/*.father:after {*/
/*content: "";*/
/*display: block;*/
/*clear: both;*/
/*}*/
.box1 {
float: right;
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box2 {
float: right;
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box3 {
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
</style>
<link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="father">
<!--<div class="box3">1</div>-->
<div class="box1">2</div>
<div class="box1">3</div>
<div style="clear: both"></div>
<!--<div class="box2" style="clear: both">4</div>-->
<!--<div class="box3">5</div>-->
<!--<div class="box3" style="clear: both">6</div>-->
</div>
</body>
</html>
运行结果:
分析:在上面这个例子中,是通过给一个空元素加上清除浮动属性实现了高度撑开。
注:这种方法需要你在浮动元素后面加上一个空div,这样会造成元素的浪费;同时当结构是ul-li元素的时候,因为ul标签里面只能有li标签,你不可能在ul标签里面加入div空元素。
4.2设置父元素的高度
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.box-wrapper {
height:50px;
border: 5px solid red;
}
.box1 {
float: right;
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box2 {
float: right;
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box3 {
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
</style>
<link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
<!--<div class="box3">1</div>-->
<div class="box1">2</div>
<div class="box1">3</div>
<!--<div class="box2" style="clear: both">4</div>-->
<!--<div class="box3">5</div>-->
<!--<div class="box3" style="clear: both">6</div>-->
</div>
</body>
</html>
运行结果:
分析:缺点从结果里面可以看得清清楚楚:就是不灵活。
4.3父级添加overflow属性
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.box-wrapper {
border: 5px solid red;
overflow: hidden;
}
.box1 {
float: right;
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box2 {
float: right;
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box3 {
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
</style>
<link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
<!--<div class="box3">1</div>-->
<div class="box1">2</div>
<div class="box1">3</div>
<!--<div class="box2" style="clear: both">4</div>-->
<!--<div class="box3">5</div>-->
<!--<div class="box3" style="clear: both">6</div>-->
</div>
</body>
</html>
运行结果:
overflow属性详解
上面的示例就是设置的hidden,所以没有浮动元素里面的数字的下半部分被修剪了。当把overflow的值设置为scroll的时候,结果如下:
当把overflow的值设为auto的时候,结果如下:
两者对比可以发现,当为scroll的时候,右侧出现了滚动条,虽然下方没有出现,但是如果说你长度也超出了,是会出现滚动条的;但是值为auto的时候,下方没有滚动条。
同时,要特别注意,这种方法在下拉列表框的情况下不能使用。原因是overflow本来就是为了解决高度溢出的问题的,而你下拉列表出来的时候肯定是比你自身高度高的,会把下拉列表隐藏掉。
4.4父级加伪类after
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.father {
border: 5px solid red;
}
.father:after {
content: "";
display: block;
clear: both;
}
.box1 {
float: right;
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box2 {
float: right;
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
.box3 {
width: 50px;
height: 50px;
margin: 20px;
background-color: green;
font-size: 80px;
}
</style>
<link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="father">
<!--<div class="box3">1</div>-->
<div class="box1">2</div>
<div class="box1">3</div>
<!--<div style="clear: both"></div>-->
<!--<div class="box2" style="clear: both">4</div>-->
<!--<div class="box3">5</div>-->
<!--<div class="box3" style="clear: both">6</div>-->
</div>
</body>
</html>
运行结果:
分析:这个方式其实跟第一个方式有点像,但是这个操作方式是一个类选择器,比第一个好使,所以推荐用这个去做。