0%

css-position

概述

position是CSS中非常重要的一个属性,也是面试中常考的考点之一!比如昨天我的面试中面试官就问我,absolute和fixed有什么区别?可惜我没有答上来。

那么这个position到底代表什么呢?顾名思义,就是位置,position决定了浏览器如何确定一个元素的位置。来看一下官方的定义:

1
2
The position CSS property sets how an element is positioned in a document. 
The top, right, bottom, and left properties determine the final location of positioned elements.

我们翻译一下这段话:position属性设置了一个元素如何在文档中定位。top, right, bottom, left属性决定了定位元素的最终位置。也就是说:position决定了如何放置一个元素,toprightbottomleft决定了元素的最终位置。

position的取值有5种,分别是:staticrelativeabsolutefixedsticky。下面我们来详细了解一下这5种取值。

positioned element

A positioned element is an element whose computed position value is either relative, absolute, fixed, or sticky. (In other words, it’s anything except static.)

说白了,只要元素的position属性不是static,那么这个元素就是一个positioned element

static

这个是默认值,可以这么说,平时开发的时候我们基本用不到这个值,因为它什么也不做,元素就是正常按照文档流一个一个排列就完了。而且由于是默认值,如果不设置position属性,那么元素就是static的。

1
2
3
4
5
<body>
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
div {
width: 100px;
height: 100px;
}
.div1 {
background-color: red;
}
.div2 {
background-color: green;
}
.div3 {
background-color: blue;
}

static

注意在position: static模式下,top, right, bottom, left是不起作用的,因为这些属性只对positioned elements有效。

1
2
3
4
#child {
top: 20px; /* This doesn't work! need nonstatic position */
background-color: red;
}

relative

记得之前有一次面试,面试官突然问我,position: relative你知道吧,我说那必须知道啊!然后他说:那么你说说relative到底相对的是谁?我一下就懵了,之前根本没有思考过这个问题。其实答案很简单,相对的是元素自己本来的位置。也就是说,relative是相对于元素自己本来的位置进行定位的。- 注意不是相对于父元素,这是误解。

下图中绿色方块定位方式设置为relative,相对其原始位置向右偏移100像素,向下偏移20像素,原始位置保留,没有影响红色方块和蓝色方块。

1
2
3
4
5
<body>
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
div {
width: 100px;
height: 100px;
}
.div1 {
background-color: red;
}
.div2 {
position: relative;
top: 20px;
left: 100px;
background-color: green;
}
.div3 {
background-color: blue;
}

relative

设置为relative的元素不会脱离文档流,最终位置相对于元素自己本来的位置进行偏移。原始的位置会保留,不影响其他元素(子元素除外)布局。

注意:relative会创建一个stack context,详情请看这里.

absolute

absolute是指绝对定位,它是相对于最近的非static定位的父元素进行定位的。如果没有非static定位的父元素,那么它是相对于<html>元素进行定位的。

标记为position: absolute的元素会脱离文档流,不占据空间,不影响其他元素的布局。下图中绿色方块定位方式设置为absolute,相对于其最近的非static定位的父元素(body)进行定位,向右偏移100像素,向下偏移20像素,原始位置不保留,影响蓝色方块的布局(蓝色方块补充了绿色方块原来的位置)

1
2
3
4
5
6
7
<body>
<div class="container">
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
</div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
div {
width: 100px;
height: 100px;
}
.div1 {
background-color: red;
}
.div2 {
position: absolute;
top: 20px;
left: 100px;
background-color: green;
}
.div3 {
background-color: blue;
}

absolute

fixed

fixedabsolute非常相似,元素也会脱离文档流,不同的是fixed是相对于viewport进行定位的。也就是说,无论你怎么滚动页面,fixed元素都会固定在浏览器视口的某个位置。(仿佛固定在屏幕上一样)

fixed的使用场景有很多,比如常见的页面右下角的返回顶部按钮,基本都是用fixed实现的。比如下面这个例子,注意这种场景不能使用absolute来实现,否则当页面滚动时,元素会跟着滚动。

1
2
3
4
5
#child {
position: fixed;
bottom: 32px;
right: 32px;
}

sticky

sticky - 黏性的;黏的,其实从这个名字就可以看出来,这种布局可以实现黏性效果,比如常见的吸顶效果(当页面滚动时,某个元素,比如顶部菜单栏固定不动),下面我们看看如何实现sticky效果。

1
2
3
<div class="container">
<div class="content">This is a sticky bar</div>
</div>
1
2
3
4
5
6
7
8
9
div.container {
height: 500vh; // 500个视口高度,使页面可以垂直滚动
}
div.content {
position: sticky; // 设置为sticky
top: 16px; // 当滚动至距离父元素顶部16px时,元素固定,也就是变得sticky.
height: 64px;
background-color: #ad1414;
}

sticky元素不会脱离文档流,它会按正常的文档流进行布局,但是当页面滚动至临界距离时(上面设置的top: 16px),元素就会固定住,不会继续滚动了,所以sticky也是有参照元素的,它参照的元素是它最近的可滚动的祖先元素。

sticky是相对定位和固定定位的结合体。它的行为就像是relativefixed的合体,当元素在屏幕中可见时,它的行为就像relative,当元素在屏幕外时,它的行为就像fixed

position属性如何影响top, right, bottom, left的表现?

position属性的值会直接影响top, right, bottom, left的表现,具体如下:

总结

是否脱离文档流 是否保留原来位置 是否影响 top/bottom/left/right 参照元素 是否创建堆叠上下文
static 无(按照正常文档流布局)
relative 元素自身原本的位置 否(除非设置了 z-index 或其他触发条件)
absolute 最近的已定位祖先元素(非 static),否则为 <html> 否(除非设置了 z-index 或其他触发条件)
fixed 浏览器视口(viewport) 否(除非设置了 z-index 或其他触发条件)
sticky 部分(滚动时脱离) 元素原本的位置与视口之间的相对关系 否(除非设置了 z-index 或其他触发条件)

References

  1. https://developer.mozilla.org/en-US/docs/Web/CSS/position