# CSS3教程 - 7 浮动
我们之前学的布局都是垂直方向的布局,现在开始学习水平方向的布局——浮动。
# 7.1 浮动的使用
通过浮动可以使一个元素向其父元素的左侧或右侧移动。
使用 float
属性来设置于元素的浮动:
float: left;
:将元素浮动到父元素的左侧;float: right;
:将元素浮动到父元素的右侧;float: none;
:取消浮动,默认值。
举个栗子:
<style>
.box1 {
width: 100px;
height: 100px;
background-color: red;
}
.box2 {
width: 120px;
height: 120px;
background-color: blue;
}
</style>
<body>
<div class="box1"></div>
<div class="box2"></div>
</body>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
上面是 box1 和 box2 都不浮动,效果如下:
都不浮动的情况下,一个元素在其父元素中,水平布局必须要满足以下的等式:
margin-left
+ border-left
+ padding-left
+ width
+ padding-right
+ border-right
+ margin-right
= 其父元素的宽度
虽然 box1 右侧有很大的空间,但是根据上面的公式,右侧实际上都是 box1的 margin-right
,所以 box2 只能在下面。
下面设置让 box1左浮动
.box1 {
width: 100px;
height: 100px;
background-color: red;
float: left;
}
2
3
4
5
6
显示如下:
我们会发现,box1 左浮动后,它的位置没有变,但是 box2 向上移动到了 box1 下面。这是为什么呢?
这是因为 box1 设置左浮动后,box1 会向父元素的左侧移动,所以它移动到了父元素的最左侧。同时一个元素设置了浮动以后,它就脱离了文档流,不再占据文档流中的位置,所以 box2 会向上移动。
下面设置让 box1 右浮动
.box1 {
width: 100px;
height: 100px;
background-color: red;
float: right;
}
2
3
4
5
6
显示如下:
box1 移动到了父元素的最右侧,box1 脱离了文档流后, box2 会向上移动。
通过上面可以发现:
- 元素设置浮动以后,水平布局的等式便不需要强制成立;
- 设置浮动以后,元素会向父元素的左侧或右侧移动;
- 元素设置浮动以后,会完全从文档流中脱离,不再占用文档流的位置,所以元素下边的还在文档流中的元素会自动向上移动;
- 浮动元素默认不会从父元素中移出,不进行特殊设置,不会超出父元素的左、右边界。
所以如果要实现水平方向的布局,只需要让元素都浮动起来排列:
<style>
.box1 {
width: 100px;
height: 100px;
background-color: red;
float: left;
}
.box2 {
width: 100px;
height: 100px;
background-color: blue;
float: left;
}
.box3 {
width: 100px;
height: 100px;
background-color: green;
float: left;
}
</style>
<body>
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</body>
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
显示如下:
如果想要调整上面 box1、box2的顺序呢,那么需要调整结构,将 box2 写到 box1前面。
<body>
<div class="box2"></div>
<div class="box1"></div>
<div class="box3"></div>
</body>
2
3
4
5
因为浮动元素向左或向右移动时,不会超过前边的浮动元素。
再举个栗子,下面我们设置了box1、box2左浮动,box3右浮动:
<style>
.box1 {
width: 300px; /* 修改了宽度 */
height: 100px;
background-color: red;
float: left;
}
.box2 {
width: 300px; /* 修改了宽度 */
height: 100px;
background-color: blue;
float: left;
}
.box3 {
width: 100px;
height: 100px;
background-color: green;
float: right;
}
</style>
<body>
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</body>
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
显示如下,当窗口够宽时,显示如下:
当缩小窗口时,box3 会被挤到第二行:
继续缩小窗口,box2 也被挤到第二行了,虽然 box1 后面有很多空间,但是box3 也不会排列到 box1 后面。
从上面可以看出:浮动元素向左或向右浮动时,都不会超过前边的浮动元素,而且浮动元素的上边缘不会超过前面的浮动的兄弟元素的上边缘,最多就是和它一样高。
刚才我们在测试的时候,是将前面的元素浮动,脱离文档流后,后面的元素会向上移动,如果前面的元素不浮动,将后面的元素浮动呢?
<style>
.box1 {
width: 100px;
height: 100px;
background-color: red;
}
.box2 {
width: 100px;
height: 100px;
background-color: blue;
float: left;
}
</style>
<body>
<div class="box1"></div>
<div class="box2"></div>
</body>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- 前面 box1 不浮动,后面 box2 浮动。
显示如下:
可以发现,如果浮动元素的上边是一个没有浮动的块元素,则浮动元素无法上移。
另外浮动元素不会盖住文字,文字会自动环绕在浮动元素的周围,所以我们可以利用浮动来设置文字环绕图片的效果。
举个栗子:
<style>
.box1 {
width: 100px;
height: 100px;
background-color: red;
float: left;
}
</style>
<body>
<div class="box1"></div>
<p>
我与父亲不相见已二年余了,我最不能忘记的是他的背影。
那年冬天,祖母死了,父亲的差使也交卸了,正是祸不单行的日子,我从北京到徐州,打算跟着父亲奔丧回家。到徐州见着父亲,看见满院狼藉的东西,又想起祖母,不禁簌簌地流下眼泪。父亲说,“事已如此,不必难过,好在天无绝人之路!”回家变卖典质,父亲还了亏空;又借钱办了丧事。这些日子,家中光景很是惨淡,一半为了丧事,一半为了父亲赋闲。丧事完毕,父亲要到南京谋事,我也要回北京念书,我们便同行。到南京时,有朋友约去游逛,勾留了一日;第二日上午便须渡江到浦口,下午上车北去。父亲因为事忙,本已说定不送我,叫旅馆里一个熟识的茶房陪我同去。他再三嘱咐茶房,甚是仔细。但他终于不放心,怕茶房不妥帖;颇踌躇了一会。其实我那年已二十岁,北京已来往过两三次,是没有甚么要紧的了。他踌躇了一会,终于决定还是自己送我去。我两回劝他不必去;他只说,“不要紧,他们去不好!”
</p>
</body>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
在上面设置了 box1 浮动,那么 <p>
标签将上移,但是并没有被 box1 挡住,而是环绕在 box1 周围。
显示如下:
总结:
- 设置浮动以后,元素会向父元素的左侧或右侧移动;
- 元素设置浮动以后,会完全从文档流中脱离,不再占用文档流的位置,所以元素下边的还在文档流中的元素会自动向上移动;
- 浮动元素向左或向右浮动时,都不会超过前边的浮动元素,且浮动元素的上边缘不会超过前面的浮动的兄弟元素的上边缘,最多就是和它一样高;
- 浮动元素默认不会从父元素中移出,不进行特殊设置,不会超出父元素的左、右边界;
- 如果浮动元素的上边是一个没有浮动的块元素,则浮动元素无法上移;
- 浮动元素不会盖住文字,文字会自动环绕在浮动元素的周围;
# 7.2 脱离文档流的特点
# 1 块元素
先看一下块元素浮动后的特点。
举个栗子:
<style>
.box1 {
background-color: red;
}
.box2 {
background-color: #CCCCCC;
height: 50px;
}
</style>
<body>
<div class="box1">foooor</div>
<div class="box2">foooor</div>
</body>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
显示如下:
设置 box1 浮动后:
.box1 {
background-color: red;
float: left;
}
2
3
4
显示如下:
可以看到:
- 块元素浮动后,从文档流中脱离,元素不再独占页面的一行;
- 脱离文档流以后,如果不指定宽度和高度,块元素的宽度和高度默认都被内容撑开;
# 2 行内元素
下面看一下行内元素设置浮动后,脱离文档流后的特点。
举个栗子:
<style>
span {
width: 200px;
height: 200px;
background-color: red;
}
</style>
<body>
<span>这是一个span</span>
</body>
2
3
4
5
6
7
8
9
10
11
行内元素不支持设置宽度和高度,所以显示如下:
设置 span 浮动后:
span {
width: 200px;
height: 200px;
background-color: red;
float: left;
}
2
3
4
5
6
显示如下:
可以看到:
- 行内元素脱离文档流以后会,特点和块元素一样,所以可以设置宽度和高度了;
- 所以元素脱离文档流后,就不需要再区分块元素和行内元素了;
# 7.3 导航条练习
下面来进行一个练习,实现 W3school 的导航条。
显示效果:
实现上图红色框框起来的部分。
其实实现的方式不是固定的,有很多方式都可以实现,下面拘泥于当前的实现方式,当前只是提供一种思路。
# 1 编写框架
首先使用 HTML 实现整体的框架。
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style/reset.css" />
<style>
</style>
</head>
<body>
<ul class="nav">
<li><a href="#">HTML/CSS</a></li>
<li><a href="#">Browser Side</a></li>
<li><a href="#">Server Side</a></li>
<li><a href="#">Programming</a></li>
<li><a href="#">XML</a></li>
<li><a href="#">Web Building</a></li>
<li><a href="#">Reference</a></li>
</ul>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- 首先引入
reset.css
(盒子模型章节讲过),去除默认样式。 - 然后使用
<ul>
、<li>
、<a>
实现结构。
显示如下:
# 2 编写CSS样式
- 给
<ul class="nav">
添加样式,设置宽高,背景颜色,屏幕居中; - 设置
<li>
为浮动,水平排列,这里设置行高,可以让文字垂直居中; - 设置
<a>
标签的样式。
<style>
.nav {
width: 1180px;
height: 48px;
background-color: #e8e7e3;
margin: 50px auto; /* 左右margin auto,设置导航条居中,盒子模型章节讲过 */
}
/* li整体布局 */
.nav li {
float: left; /* 浮动li元素 */
line-height: 48px; /* 设置行高,这样文字就垂直居中了 */
}
.nav a {
display: block; /** 设置为块元素,行高会继承自父元素,这样也就设置了a的高度和li的高度相同 **/
font-size: 18px;
color: #777777;
text-decoration: none; /* 去除下划线 */
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
显示如下:
继续调整一下各个 <li>
的间距,和 <a>
标签,鼠标悬浮的效果:
.nav a {
display: block;
font-size: 18px;
color: #777777;
text-decoration: none;
padding: 0 38px; /* 让文字有一定的距离 */;
}
/* 超链接悬浮效果 */
.nav li a:hover {
background-color: #3f3f3f;
color: #e8e7e3;
}
2
3
4
5
6
7
8
9
10
11
12
13
显示效果:
这里有一个地方需要注意:每个菜单的宽度是不一样的,单词长的,菜单也长,所以这里使用 padding
来调整 <li>
的宽度,让每个菜单中的文字有距离,但是有一个问题,padding: 0 38px;
不能保证最终各个 <li>
的宽度之和等于整个 <ul>
的宽度,如果小于最终宽度,会导致选中最后一个菜单的时候,和 <ul>
的背景不对齐。如下图:
如果出现上面这种情况,可以调整一下 <ul>
的宽度,让它等于所有 <li>
的宽度之和,我上面就是这么设置的,所以宽度是刚刚好的。
或者也可以把多出来的部分增加到最后一个菜单上,单独调整一下最后一个菜单的宽度:
/* 单独设置最后一个li元素中的a元素,也可以调整左右的padding,使文字更居中 */
.nav li:last-child a {
padding-right: 48px;
}
2
3
4
最终显示效果:
最终全部代码:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style/reset.css" />
<style>
.nav {
width: 1190px;
height: 48px;
background-color: #e8e7e3;
margin: 50px auto; /* 左右margin auto,设置导航条居中,盒子模型章节讲过 */
}
/* li整体布局 */
.nav li {
float: left; /* 浮动li元素 */
line-height: 48px; /* 设置行高,这样文字就垂直居中了 */
}
.nav a {
display: block; /** 设置为块元素,行高会继承自父元素,也就是li **/
font-size: 18px;
color: #777777;
text-decoration: none; /* 去除下划线 */
padding: 0 38px; /* 让li元素有一定的距离 */;
}
/* 超链接悬浮效果 */
.nav li a:hover {
background-color: #3f3f3f;
color: #e8e7e3;
}
/* 单独设置最后一个li元素中的a元素 */
.nav li:last-child a {
padding-right: 48px;
}
</style>
</head>
<body>
<ul class="nav">
<li><a href="#">HTML/CSS</a></li>
<li><a href="#">Browser Side</a></li>
<li><a href="#">Server Side</a></li>
<li><a href="#">Programming</a></li>
<li><a href="#">XML</a></li>
<li><a href="#">Web Building</a></li>
<li><a href="#">Reference</a></li>
</ul>
</body>
</html>
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
# 7.4 布局练习
下面实现一个下面这样的布局:
- 上面是导航栏、中间是内容区域、底部是footer;
- 中间的内容分为左、中、右三个部分。
# 1 编写框架
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style/reset.css" />
<style>
header {
width: 1000px;
height: 80px;
background-color: lightskyblue;
margin: 0 auto;
}
main {
width: 1000px;
height: 500px;
background-color: lightcoral;
margin: 10px auto;
}
footer {
width: 1000px;
height: 80px;
background-color: lightgreen;
margin: 0 auto;
}
</style>
</head>
<body>
<!-- 头部 -->
<header></header>
<!-- 中间主要区域 -->
<main>
<!-- 左侧区域 -->
<nav></nav>
<!-- 中间区域 -->
<section></section>
<!-- 右侧区域 -->
<aside></aside>
</main>
<!-- footer -->
<footer></footer>
</body>
</html>
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
- 在上面使用了各个语义标签定义了各个布局区域,当然你所有区域都使用 div 也是可以的;
- 单独定义区域,是显示不出任何内容的,所以给各个区域设置了大小、背景颜色、并设置了居中,并给中间的区域设置了上下的 margin;
显示如下:
# 2 继续编写CSS样式
下面继续编写 CSS,设置中间部分左、中、右三个区域的布局
main > nav {
width: 200px;
height: 100%;
background-color: lightcoral;
float: left;
}
main > section {
width: 600px;
height: 100%;
background-color: lightcyan;
float: left;
}
main > aside {
width: 200px;
height: 100%;
background-color: lightyellow;
float: left;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- 设置三个区域的宽度;设置高度和中间区域的高度一样 100%;
- 设置三个区域都是左浮动,横向排列
显示如下:
设置一下中间左、中、右三个区域的间隔。设置中间部分左右的间隔即可,不过还需要调整一下宽度,否则超过了整个区域的宽度,右侧区域会被挤下去:
main > section {
width: 580px; /* 总宽度减去margin的宽度 */
height: 100%;
background-color: lightcyan;
float: left;
margin: 0 10px; /* 左右各10px */
}
2
3
4
5
6
7
最终显示效果:
最终代码:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style/reset.css" />
<style>
/* 设置头部区域样式 */
header {
width: 1000px;
height: 80px;
background-color: lightpink;
margin: 0 auto;
}
/* 设置内容区域样式 */
main {
width: 1000px;
height: 500px;
background-color: lightgray;
margin: 10px auto;
}
main > nav {
width: 200px;
height: 100%;
background-color: lightcoral;
float: left;
}
main > section {
width: 580px; /* 总宽度减去margin的宽度 */
height: 100%;
background-color: lightcyan;
float: left;
margin: 0 10px; /* 左右各10px */
}
main > aside {
width: 200px;
height: 100%;
background-color: lightyellow;
float: left;
}
/* 设置底部区域样式 */
footer {
width: 1000px;
height: 80px;
background-color: lightgreen;
margin: 0 auto;
}
</style>
</head>
<body>
<!-- 头部 -->
<header></header>
<!-- 中间主要区域 -->
<main>
<!-- 左侧区域 -->
<nav></nav>
<!-- 中间区域 -->
<section></section>
<!-- 右侧区域 -->
<aside></aside>
</main>
<!-- footer -->
<footer></footer>
</body>
</html>
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
在现代 CSS 中,浮动已经不再是布局的首选方法,更多的是使用 Flexbox 或 Grid 来处理布局,后面再讲。
另外上面的布局存在一个问题,就是中间内容区域的高度是定死了,就是 500px,这样如果内容区域的内容很多,将无法完整显示内容或只能使用滚动条,正常情况下应该是内容区域的高度随着内容自动扩展。但是这里又不能不定死内容区域的高度,因为其中的子元素是浮动的,这里涉及的一个问题就是父元素的高度塌陷问题,下一个章节讲。
← 06-盒子模型-2 08-高度塌陷与BFC →