浮动规则,浮动案例,浮动导致的父元素高度塌陷问题,清除浮动方法
1. 认识浮动
float 属性可以指定一个元素应
沿其容器的左侧或右侧放置,允许文本和内联元素环绕它- float 属性最初只用于在一段文本内浮动图像, 实现文字环绕的效果
- 但是早期的CSS标准中并没有提供好的左右布局方案,因此在一段时间里面它成为网页多列布局的最常用工具
绝对定位、浮动都会让元素脱离标准流,以达到灵活布局的效果
可以通过float属性让元素产生浮动效果,float的常用取值
- none:不浮动,默认值
- left:向左浮动
- right:向右浮动
2. 浮动规则
元素一旦浮动后, 脱离标准流
朝着向左或向右方向移动,直到自己的边界
紧贴着包含块(一般是父元素)或者其他浮动元素的边界为止定位元素会层叠在浮动元素上面
如果元素是向左(右)浮动,浮动元素的左(右)边界不能超出包含块的左(右)边界
浮动元素之间
不能层叠- 如果一个元素浮动,另一个浮动元素已经在那个位置了,后浮动的元素将紧贴着前一个浮动元素(左浮找左浮,右浮找右浮)
- 如果水平方向剩余的空间不够显示浮动元素,浮动元素将向下移动,直到有充足的空间为止
浮动元素不能与行内级内容层叠,行内级内容将会被浮动元素推出
- 比如行内级元素、inline-block元素、块级元素的文字内容
行内级元素、inline-block元素浮动后,其顶部将与所在行的顶部对齐

1 | <div class="container"> |
3. 解决水平间隙
存在换行导致的水平间隙

1
2
3
4
5
6
7
8
9
10
11<style>
span {
background-color: orange;
}
</style>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>解决行内级元素、inline-block元素的水平间隙问题

删除换行符(不推荐)
1
<div><span>1</span><span>2</span><span>3</span></div>
影响代码的阅读和美观
将父级元素的font-size设为0,但子元素必须设置font-size(不推荐)
1
2
3
4
5
6div {
font-size: 0;
}
div span{
font-size: 14px;
}使用浮动
1
2
3div span {
float: left;
}浮动会使后浮动的元素紧贴着前一个浮动元素
4. 浮动案例
4.1. 百度页码

HTML
1
div.content>ul>li.item*11>a[href="#"]{$}
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56/* 样式重置 */
body, ul, li, a {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
a {
text-decoration: none;
color: #333;
}
/* 内容样式 */
.content {
width: 482px;
height: 36px;
background-color: #f2f2f2;
padding: 5px;
margin: 0 auto;
}
.content ul {
margin-right: -5px;
}
ul li.item {
float: left;
margin-right: 5px;
}
ul li.item a {
display: block;
width: 36px;
height: 36px;
border-radius: 6px;
font-size: 14px;
text-align: center;
line-height: 36px;
background-color: #fff;
}
ul li.item.next a{
width: 72px;
}
ul li.item.active a,
ul li.item a:hover {
background-color: #3951b3;
color: #fff;
font-size: 16px;
}
4.2. 最右浮动块的margin-right问题
一行4个元素,要求两边元素贴边的情况下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17.content>div.item.item$*4{$}
.content {
width: 215px;
height: 105px;
background-color: red;
}
.item {
width: 50px;
height: 50px;
background-color: pink;
float: left;
margin: 0 5px 5px 0;
}每个块向左浮动的时候,设置每个块的margin-right为5px,最后一块会因为margin-right导致在第一行放不下而掉落到第二层

解决方法
设置 :nth-child(4n){ margin-right:0; }
- 存在兼容性问题,IE6-8不支持,而float本身有很好的兼容性
修改div.content的整体宽度为220px,修改背景色,从而视觉上”看不出来“贴不贴边
- 问题其实没有根本解决
嵌套div,设置其
margin-right:-5px- width默认为auto
- 父盒子宽度 = 子盒子宽度+子盒子margin-left+子盒子margin-right
- 215 = auto + 0 - 5 -> auto = 220 -> 子盒子div.box宽度为220px,但是这不影响整个div.content的布局
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<div class="content">
<div class="box">
<div class="item item1">1</div>
<div class="item item2">2</div>
<div class="item item3">3</div>
<div class="item item4">4</div>
</div>
</div>
<style>
.content {
width: 215px;
height: 105px;
background-color: red;
}
.content .box {
margin-right: -5px;
}
.item {
width: 50px;
height: 50px;
background-color: pink;
float: left;
margin: 0 5px 5px 0;
}
</style>
4.3. 京东多列布局-同高

HTML
1
.content>ul>li.item*8>a[href="#"]
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43/* 重置 */
body,ul,li,a,img,p,span{
margin: 0;
padding: 0;
}
ul,li {
list-style: none;
}
a {
text-decoration: none;
color: #333;
}
/* 样式 */
.content {
width: 830px;
height: 465px;
margin: 0 auto;
margin-top: 10px;
background-color: red;
}
.content ul {
margin-right: -10px;
}
ul li.item {
float: left;
margin: 0 10px 10px 0;
}
ul li.item a {
display: block;
width: 200px;
height: 230px;
box-sizing: border-box;
padding: 5px 10px;
background-color: pink;
}
4.4. 京东多列布局-不同高

HTML
1
.content>.wrapper>.item.left*2+.item.right*12
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21.content {
width: 1190px;
height: 750px;
margin: 0 auto;
background-color: red;
}
.wrapper {
margin-right: -10px;
}
.item {
width: 290px;
margin: 0 10px 10px 0;
background-color: pink;
float: left;
}
.item.left {
height: 370px;
}
.item.right {
height: 180px;
}
4.5. 小米页面布局-不同高

HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25<div class="mi_wrapper ai_dress">
<!-- 导航栏 -->
<div class="header">
<div class="left_area">
<h3 class="title">智能穿戴</h3>
</div>
<div class="right_area">
<a href="#" class="hot active">热门</a>
<a href="#" class="dress">穿戴</a>
</div>
</div>
<!-- 列表 -->
<ul class="list">
<li class="item item1"><a href="#">1</a></li>
<li class="item item2"><a href="#">2</a></li>
<li class="item item3"><a href="#">3</a></li>
<li class="item item4"><a href="#">4</a></li>
<li class="item item5"><a href="#">5</a></li>
<li class="item item6"><a href="#">6</a></li>
<li class="item item7"><a href="#">7</a></li>
<li class="item item8"><a href="#">8</a></li>
<li class="item item9"><a href="#">9</a></li>
<li class="item item10"><a href="#">10</a></li>
</ul>
</div>CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93/* 重置元素样式 */
body,div,h3,a,ul,li {
margin: 0;
padding: 0;
}
body {
color: #333;
font-size: 16px;
}
a {
text-decoration: none;
color: #333;
}
ul,li {
list-style: none;
}
.mi_wrapper {
width: 1226px;
margin: 0 auto;
}
/* 配置样式 */
.ai_dress {
height: 686px;
background-color: #f5f5f5;
}
/* 顶部信息 */
.ai_dress .header {
height: 58px;
/* 垂直居中 */
line-height: 58px;
}
/* 顶部信息-标题 */
.ai_dress .header .left_area {
float: left;
}
.ai_dress .header .left_area h3 {
font-weight: normal;
font-size: 20px;
}
/* 顶部信息-导航栏 */
.ai_dress .header .right_area {
float: right;
}
.ai_dress .header .right_area a {
margin-left: 20px;
padding-bottom: 5px;
}
/* 顶部信息-导航栏选中状态*/
.ai_dress .header .right_area a.active,
.ai_dress .header .right_area a:hover{
border-bottom: 2px solid #ff6700;
color: #ff6700;
}
/* 10个展示项 */
.ai_dress .list {
margin-left: -14px;
}
.ai_dress .list .item {
float: left;
width: 234px;
height: 300px;
margin: 0 0 14px 14px;
background-color: pink;
transition: all .3s ease-in-out;
}
/* 选中项-盒子上移 */
.ai_dress .list .item:hover {
box-shadow: 0 0 10px #333;
transform: translate(0px,-5px);
}
/* 第一个高度占满 */
.ai_dress .list .item1 {
height: 614px;
}
/* 最后两个高度减半 */
.ai_dress .list .item9,
.ai_dress .list .item10 {
height: 143px;
}
.ai_dress .list .item a {
display: block;
width: 100%;
height: 100%;
}
4.6. 考拉页面布局-边框问题
HTML
1
2
3
4
5
6
7
8
9<div class="content">
<div class="box">
<div class="item first"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item end"></div>
</div>
</div>
4.6.1. div.box 带边框(不推荐)
1 | div { |

- 最初,每个div.item的宽度设为220px
- 首先,div.content的宽度 = div.box的宽度 + div.box的margin-left + div.box的margin-right
- 1110 = auto + 0 + 0,auto = 1110,div.box的盒子宽度为1110px
- 其次,div.box盒子宽度 = div.box的内容宽度 + border-left + border-right + margin-left + margin-right
- div.box 有左边框5px,因此div.box的内容宽度为1095px,放不下5个220px=1110px
- 所以需要设置 margin-right: -5px; 将div.box的内容宽度扩为 1110px
- 但是,导致div.box的盒子宽度变为 1105px (1110 = auto + 0 - 5),
最右边多个5px- 将
最后一个盒子宽度改为215px,此时就不需要div.box的margin-right
- 将
4.6.2. div.item 自缩进(推荐)
1 | .content { |

- 每个 div.item 原始宽度为220px,都是左浮动,本来是紧贴着的,设置边框导致盒子之间的距离加宽为10px
- 解决:设置每个div.item盒子 margin-left: -5px,后一个就盖在了前一个的右边框上
- 新问题:盒子都左移导致整体右边多个25px的空隙
- 解决:将div.item的宽度设为225px
- 新问题:整体左移导致第一个盒子
左边多出5px- 解决:
第一个盒子宽度设为 220px,将div.item改为 margin-right: -5px;
- 解决:
4.6.3. 多列不同高

对于div.item-center元素
原本整体高度希望是540px,元素高度都是270px
每个元素都有上右下边5px边框,上下两个元素中间就会因为上下边框问题导致间距变为10px
将每个元素都margin-bottom:-5px; 向下移动5px,上边元素叠在下边元素之上5px来解决间距问题
向下移动因为元素覆盖导致元素的高度减少为265px,div.item-center内出现剩余空间,所以将元素高度设置为275px
向下移动也导致 div.item-center 整体下边超出5px,所以div.item-left的高度设为545px
对于div.item-right元素
- 原本整体高度也希望是540px,元素高度依次为 60px,120px,120px,120px,120px
- 每个元素也都有上右下边5px边框,也进行了向下移动margin-bottom:-5px;
- 由于元素的覆盖,下边4个元素的高度变为115px,所以需要将这4个元素高度设为125px
- 但div.item-left,div.item-center的整体高度是545px,就需要div.item-right内部高度增加5px,选择将第一个元素高度设为65px
HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40<div class="kl_wrapper sport">
<div class="header">
<div class="left_area">
<h1>运动户外</h1>
<ul class="word">
<li class="item"><span>热搜词:</span></li>
<li class="item active"><a href="#">阿迪达斯</a></li>
<li class="item item3"><a href="#">耐克</a></li>
<li class="item active"><a href="#">斯凯奇</a></li>
<li class="item active"><a href="#">安德玛</a></li>
</ul>
</div>
<div class="right_area">
<a href="#">更多好货 ></a>
</div>
</div>
<div class="list">
<div class="item-left"></div>
<div class="item-center">
<div class="item"><a href="#">1</a></div>
<div class="item"><a href="#">2</a></div>
<div class="item"><a href="#">3</a></div>
<div class="item"><a href="#">4</a></div>
</div>
<div class="item-right">
<div class="item header">
<h3>最新热卖</h3>
<div class="link">
<a href="#" class="active"></a>
<a href="#"></a>
<a href="#"></a>
</div>
</div>
<div class="item"><a href="#">1</a></div>
<div class="item"><a href="#">2</a></div>
<div class="item"><a href="#">3</a></div>
<div class="item"><a href="#">4</a></div>
</div>
</div>
</div>CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132body,div,h1,a,ul,li,h3 {
margin: 0;
padding: 0;
}
body {
color: #333;
font-size: 14px;
}
a {
text-decoration: none;
color: #999;
}
ul,li {
list-style: none;
}
/* 样式 */
.kl_wrapper {
width: 1105px;
height: 650px;
margin: 0 auto;
}
.sport {
background-color: orange;
}
/* 顶部 */
.sport .header {
height: 74px;
line-height: 74px;
background-color: #f5f5f5;
}
.sport .header .left_area {
float: left;
}
.sport .header .left_area h1 {
float: left;
font-size: 22px;
margin-right: 20px;
}
.sport .header .left_area .word {
float: left;
color: #999;
position: relative;
top: 3px;
}
.sport .header .left_area .word .item {
float: left;
margin-right: 20px;
}
.sport .header .left_area .word .active a{
color: rgb(254, 6, 12);
}
.sport .header .left_area .word a:hover {
text-decoration: underline;
}
.sport .header .right_area {
float: right;
}
.sport .header .right_area a:hover {
text-decoration: underline;
}
/* 列表 */
.sport .list > div {
background-color: pink;
float: left;
}
/* 左边无边框 */
.sport .list .item-left {
width: 330px;
height: 545px;
margin-right: 5px;
}
/* 中间每个有5px上右下边框 */
.sport .list .item-center {
float: left;
width: 550px;
}
.sport .list .item-center .item {
float: left;
width: 275px;
height: 275px;
border: 5px solid #f5f5f5;
border-left: none;
box-sizing: border-box;
margin-bottom: -5px;
}
.sport .list .item-center .item a,
.sport .list .item-right .item a {
display: block;
width: 100%;
height: 100%;
}
/* 中间每个有5px上右下边框 */
.sport .list .item-right {
width: 220px;
}
.sport .list .item-right .item{
height: 125px;
border: 5px solid #f5f5f5;
border-left: none;
box-sizing: border-box;
margin-bottom: -5px;
}
.sport .list .item-right .header {
height: 65px;
line-height: 65px;
background-color: pink;
overflow: hidden;
}
.sport .list .item-right .header h3 {
float: left;
}
.sport .list .item-right .header .link {
float: right;
}
.sport .list .item-right .header .link a {
display: inline-block;
width: 5px;
height: 5px;
border-radius: 50%;
border: 2px solid #999;
margin-left: 10px;
}
.sport .list .item-right .header .link a.active,
.sport .list .item-right .header .link a:hover {
background-color: blue;
}
5. 浮动的问题 – 高度塌陷
由于浮动元素脱离了标准流,变成了脱标元素,所以不再向父元素汇报高度
- 父元素计算总高度时,就不会计算浮动子元素的高度,导致了高度坍塌的问题
解决父元素高度坍塌问题的过程,一般叫做清浮动(清理浮动、清除浮动)
清浮动的目的
- 让父元素计算总高度的时候,把浮动子元素的高度算进去
6. 认识clear属性
- clear属性是做什么的呢?
- clear 属性可以指定一个元素是否必须移动(清除浮动后)到在它之前的浮动元素下面
- clear的常用取值
- left:要求元素的顶部低于之前生成的所有左浮动元素的底部
- right:要求元素的顶部低于之前生成的所有右浮动元素的底部
- both:要求元素的顶部低于之前生成的所有浮动元素的底部
- none:默认值,无特殊要求
7. 清除浮动的方法
7.1. 设置父元素高度
- 扩展性不好(不推荐)
7.2. 额外标签法
- 在父元素最后增加一个空的块级子元素,并且让它设置clear: both
- 会增加很多无意义的空标签,维护麻烦
- 违反了结构与样式分离的原则(不推荐)
7.3. 伪元素法
7.3.1. 单伪元素清除法
- 操作:用伪元素替代额外标签
- 优点:项目中使用,直接给标签加类即可清除浮动
1 | .clearfix::atfer{ |
7.3.2. 双伪元素清除法
- 优点:项目中使用,直接给标签加类即可清除浮动
1 | .clearfix::before, |
7.4. overflow
- 给父级元素添加overflow样式方法
overflow = hidden|auto|scroll- 这种方法代码比较简洁,可以通过触发BFC方式,但是因为本身overflow的本质是溢出隐藏的效果,所以有的时候也会有一些问题存在
- 比如内容增多的时候不会自动换行导致内容被隐藏掉,无法显示出要溢出的元素
7.5. 三种方法总结
| css清除浮动方法 | 额外标签法 | 伪元素法 | overflow |
|---|---|---|---|
| 优点 | 写法简单,兼容性好 | 写法简单,兼容性好 | 结构语义化正确,可以解决塌陷问题 |
| 缺点 | 添加了无意义的标签,结构化比较差 | overflow的本质是溢出隐藏,超出元素无法显示 | 写法复杂,需要兼容 |