# CSS3教程 - 9 定位1

什么是定位?

定位是一种更高级的布局方式,通过定位可以很方便的将元素放到页面的任意位置。


比如说如果要实现下面的布局:

使用浮动或 margin 也可以实现,但是实现起来比较麻烦,另外使用浮动或 margin 很可能对其他元素的布局产生影响,而使用定位的话就很方便了。

下面来学习如何使用定位。


# 9.1 定位简介

定位使用的核心属性是 position,它定义了元素的定位类型。常见的定位类型有:

  • static(默认值)
  • relative
  • absolute
  • fixed
  • sticky

position 属性设置为除了 static 之外的值,则表示开启定位,开启定位后,我们可以使用其他的一些属性来对元素进行布局。下面就依次介绍各种定位方式。


首先我们有下面这样的代码:

<!DOCTYPE html>
<html>
  <head>
    <style>
      .box1 {
        width: 100px;
        height: 100px;
        background-color: skyblue;
      }

      .box2 {
        width: 100px;
        height: 100px;
        background-color: lightpink;
      }

      .box3 {
        width: 100px;
        height: 100px;
        background-color: lightgreen;
      }
    </style>
  </head>

  <body>
    <div class="box1">1</div>
    <div class="box2">2</div>
    <div class="box3">3</div>
  </body>
</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
  • 编写了三个 div ,设置了不同的背景颜色而已。

显示如下:

# 9.2 static默认定位

元素的 position 的默认值就是 static,所以设置了没有任何影响,元素按正常文档流排列。

生活没有任何波澜,过!

# 9.3 relative相对定位

当元素的 position 属性设置为 relative 时,表示开启相对定位。开启相对定位后,我们可以使用 toprightbottomleft 四个属性设置元素的相对位置。设置元素相对于自己原来位置的偏移

举个栗子:

在上面代码的基础上修改:

.box2 {
  position: relative;  /* 相対定位 */
  left: 100px;  /* 左侧偏移100px,也就是右移100px */
  width: 100px;
  height: 100px;
  background-color: lightpink;
}
1
2
3
4
5
6
7
  • 在上面的代码中,使用 positionbox2 开启相对定位;
  • 开启相对定位后,就可以使用 toprightbottomleft 四个属性设置 box2 相对于它原来位置的偏移。上面使用了 left 表示相对于 box2 原来的位置左边偏移了 100px,也就是右移 100px。

显示如下:


元素在水平方向的偏移由 leftright 两个属性控制,一般只会使用其中一个:

  • left 越大,定位元素越靠右,可以为负,则向左移动
  • right 越大,定位元素越靠左,可以为负,则向右移动

同样,元素在垂直方向的偏移由 topbottom 两个属性控制,一般也只使用其中一个:

  • top 越大,定位元素越靠下,可以为负,则向上移动
  • bottom 越大,定位元素越靠上,可以为负,则向下移动

所以实现一开始的效果,只需要使用下面的样式就可以了:

.box2 {
  position: relative;  /* 相対定位 */
  left: 100px;  /* 右移100px */
  top: -100px;  /* 上移100px */
  width: 100px;
  height: 100px;
  background-color: lightpink;
}
1
2
3
4
5
6
7
8
  • 首先开启相对定位,然后使用 left 和 top 设置水平和垂直方向上,相对于其自身原来位置的偏移即可,是不是非常的方便。
  • 而且使用了相对定位后,只会移动自身的位置,不会对其他元素产生任何影响。

显示如下:

另外使用相对定位会提升元素的层级,例如向上移动 box2 :

.box2 {
  position: relative;  /* 相対定位 */
  left: 50px;  /* 右移50px */
  top: -50px;  /* 上移50px */
  width: 100px;
  height: 100px;
  background-color: lightpink;
}
1
2
3
4
5
6
7
8

显示如下:

可以看到 box2 遮挡了 box1,也就是 box2 的层级要比 box1 高了。

做个总结:

  • 相对定位是元素相对于它在文档流中原来的位置的定位;
  • 相对定位 不会脱离文档流 ,元素还是占用原来的位置(灵魂已出窍,肉体还占着),不会对其他元素的位置产生影响;
  • 相对定位会提升元素的层级,可以遮挡其他的元素;
  • 相对定位不会修改元素的性质,行内元素还是行内元素,块元素还是块元素。

# 9.4 absolute绝对定位

当元素的 position 属性设置为 absolute 时,表示开启绝对定位。

开启绝对定位后,元素有如下特点:

  1. 开启绝对定位后,如果不设置偏移量,元素的位置不会发生变化;
  2. 开启绝对定位后,元素会脱离文档流
  3. 开启绝对定位后,元素的性质会发生变化,和以前元素浮动脱离文档流一样,行内元素变成块元素,可以设置宽高了,块的宽高变成被内容撑开;
  4. 绝对定位会使元素提升一个层级;
  5. 绝对定位是相对于 包含块 进行定位的(下面会讲)。

所以将 box2 设置为绝对定位:

.box2 {
  position: absolute;  /* 绝对定位 */
  width: 100px;
  height: 100px;
  background-color: lightpink;
}
1
2
3
4
5
6

显示如下:

可以看到和上面描述的一致:

  1. box2 的位置没有发生变化;
  2. box2 脱离了文档流,所以box3上移了,并且 box2 元素的显示层级提升了,所以挡住了box3;

# 1 包含块

现在还没有介绍绝对定位如何定位,在介绍绝对定位如何定位之前,先介绍一个包含块的概念。

什么是包含块?

  1. 如果当前元素没有开启绝对定位,那么它的包含块就是离它最近的祖先块元素。

举个栗子:

<div>
  <span>
    <b>hello foooor!</b>
  </span>
</div>
1
2
3
4
5
  • <span> 元素的包含块就是 <div> 元素;
  • <b> 元素的包含块也是 <div> 元素, <div> 是离他最近的祖先块元素,<span> 是行内元素,不算。

  1. 如果当前元素开启了绝对定位,那么它的包含块就是离它最近,并且开启了定位的(不是static)祖先块元素。如果所有的祖先块元素都没有开启定位,那么根元素就是它的包含块,根元素就是 <html> 元素,也叫初始包含块。

# 2 定位

说完了包含块,来说绝对定位的定位方式:元素绝对定位是相对于它的包含块进行定位

举个例子:

.box2 {
  position: absolute;  /* 绝对定位 */
  top: 50px;
  left: 50px;
  width: 100px;
  height: 100px;
  background-color: lightpink;
}
1
2
3
4
5
6
7
8
  • 上面为 box2 设置了绝对定位,并设置了顶部和左侧的偏移;
  • 因为现在 box2 找不到最近的包含块,所以它的包含块是 html 元素,所以 box2 绝对定位是相对于 <html> 的,也就是左上角。

所以显示如下:


现在给 box2 添加父元素 box4,给box4 添加父元素 box5:

<!DOCTYPE html>
<html>
  <head>
    <style>
      .box1 {
        width: 100px;
        height: 100px;
        background-color: skyblue;
      }

      .box2 {
        position: absolute;  /* 绝对定位 */
        top: 50px;
        left: 50px;
        width: 100px;
        height: 100px;
        background-color: lightpink;
      }

      .box3 {
        width: 100px;
        height: 100px;
        background-color: lightgreen;
      }

      .box4 {
        width: 150px;
        height: 150px;
        background-color: lightgray;
      }

      .box5 {
        width: 200px;
        height: 200px;
        background-color: lightyellow;
      }
    </style>
  </head>

  <body>
    <div class="box1">1</div>
    <div class="box5">
      5
      <div class="box4">
        4
        <div class="box2">2</div>
      </div>
    </div>
    <div class="box3">3</div>
  </body>
</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
41
42
43
44
45
46
47
48
49
50
51

显示如下:

因为 box2 是绝对定位,div4 和 div5 没开启定位,所以 box2 的包含块还是 html 元素,所以 box2 的位置没有变化。


现在将 div5 开启相对定位:

.box5 {
  position: relative;  /* 相对定位 */;
  width: 200px;
  height: 200px;
  background-color: lightyellow;
}
1
2
3
4
5
6
  • 那么 box2 的包含块就是 box5 了,那么 box2 的绝对定位是相对于 box5 的。

显示如下:

可以看到 box2 相对于 box5 定位了。

如果将 box4 设置为相对定位,那么box2的包含块就会变为box4,box2 就会相对于box4定位:

.box2 {
  position: absolute;  /* 绝对定位 */
  top: 50px;
  left: 50px;
  width: 100px;
  height: 100px;
  background-color: lightpink;
}

.box4 {
  position: relative;  /* 相对定位 */;
  width: 150px;
  height: 150px;
  background-color: lightgray;
}

.box5 {
  position: relative;  /* 相对定位 */;
  width: 200px;
  height: 200px;
  background-color: lightyellow;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

显示如下:

所以明白了吧,元素开启绝对定位后,元素将相对于其包含块进行定位!

绝对定位在实际开发中是用的最多的,通过设置父元素为相对定位(元素位置、性质不会变化),子元素为绝对定位,也就是子绝父相,可以很方便的实现子元素在父元素中的任意定位。

# 9.5 fixed固定定位

当元素的 position 属性设置为 fixed 时,表示开启固定定位。

固定定位可以看做是绝对定位的一个特例,所以固定定位的特点和绝对定位的特点一样,例如脱离文档流、行内元素元素变块元素等。

不同的是固定定位是相对于浏览器视口(可视窗口)进行定位的,不会随着网页滚动而移动。


举个栗子:

和上面绝对定位的代码一样,但是将 box2 设置为固定定位:

<!DOCTYPE html>
<html>
  <head>
    <style>
      .box1 {
        width: 100px;
        height: 100px;
        background-color: skyblue;
      }

      .box2 {
        position: fixed;  /* 固定定位 */
        right: 0px;
        bottom: 0px;
        width: 100px;
        height: 100px;
        background-color: lightpink;
      }

      .box3 {
        width: 100px;
        height: 100px;
        background-color: lightgreen;
      }

      .box4 {
        position: relative;  
        width: 150px;
        height: 150px;
        background-color: lightgray;
      }

      .box5 {
        position: relative;
        width: 200px;
        height: 200px;
        background-color: lightyellow;
      }
    </style>
  </head>

  <body>
    <div class="box1">1</div>
    <div class="box5">
      5
      <div class="box4">
        4
        <div class="box2">2</div>
      </div>
    </div>
    <div class="box3">3</div>
  </body>
</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
41
42
43
44
45
46
47
48
49
50
51
52
53
  • 对 box2 开启绝对定位,同时通过 right 和 bottom 来设置偏移。

显示如下:

可以看到 right 和 bottom 的偏移为 0 时,box2 在窗口的右下角,是相对于整个浏览器窗口的,如果网页的内容很长,有滚动条,box2 始终在窗口右下角,不跟随着内容的滚动,一般浏览器右下角的牛皮鲜小广告,就是通过绝对定位来实现的。

# 9.6 sticky粘滞定位

当元素的 position 属性设置为 sticky 时,表示开启粘滞定位。

什么是粘滞定位?

在有一些网页上会看见,有一些菜单随着内容滚动而滚动,但是滚到某个位置(例如,最上面的时候),它就固定在那里了,不随着内容滚动了。这个就是粘滞定位,粘在那里了。


这里以之前编写的 W3School 导航条为例,添加粘滞定位:

之前的代码:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="style/reset.css" />
    <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; /* 去除下划线 */
      }

      .nav a {
        display: block;
        font-size: 18px;
        color: #777777;
        text-decoration: none;
        padding: 0 38px; /* 让文字有一定的距离 */
      }

      /* 超链接悬浮效果 */
      .nav li a:hover {
        background-color: #3f3f3f;
        color: #e8e7e3;
      }
    </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>
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

显示如下:

下面调整一下 body 的高度,让页面出现滚动条,然后给导航条添加粘滞定位:

body {
  height: 3000px;
}

.nav {
  position: sticky;  /* 粘滞定位 */
  top: 10px;   /* 偏移量,上面偏移10px*/
  width: 1180px;
  height: 48px;
  background-color: #e8e7e3;
  margin: 50px auto; 
}
1
2
3
4
5
6
7
8
9
10
11
12
  • 上面给导航条添加了粘滞定位,顶部偏移量是10px;
  • 粘滞定位也是相对于其包含块进行定位的,这里导航没有开启定位的祖先包含块,所以是 html 元素。

所以当滚动页面的时候,导航条在距离浏览器上面 10px 的时候停住,即使页面在滚动,导航条也不会动。

显示如下:

粘滞定位是一个比较新的定位方式,浏览器对这种定位方式支持的不是很好,尤其是IE,不过现在IE基本不用了,一般在进行类似效果的处理的时候,需要结合 Javascript 进行处理。