近期在找工作,发现 position 定位相关问题提到的比较多,包括自己之前参加公司面试,也会问到一些 position 定位相关问题,可是往往有将近一半的人不能够对 position 有一个清晰明确的描述。于是决定在这里把 position 属性介绍一番。
定义
规定元素的定位类型。
属性值
- static:默认值。元素按照正常文档流呈现。
- absolute:生成绝对定位的元素,该元素相对于第一个 position 值为非 static 的父元素定位(如果没有,则相对于 body 定位)。
- fixed:生成绝对(固定)定位的元素,该元素相对于浏览器窗口进行定位。
- relative:生成相对定位的元素,该元素相对于其在文档流正常位置定位。
- sticky:生成粘贴定位元素,粘贴定位是相对定位和固定定位的混合,元素在跨越特定阈值前为相对定位,之后为固定定位。因此必须指定 top、bottom、left 或 right 中的某个值,否则粘贴定位无效。该元素相对于其在文档流正常位置和最近块级祖先元素定位,即:元素为跨越阈值前,其位置为文档流正常位置;一旦跨越阈值,元素变为固定定位,只要其最近块级祖先元素在可视区域,其位置不变,最近块级祖先元素一旦消失,其也会随着消失。(语言表述毕竟有所局限,但此属性值威力巨大,强烈建议各位看官自己动手试上一试!)
- inherit:从父元素继承 position 属性值。
元素性质
- 当属性值为 absolute 或 fixed 时,不管元素本身类型如何,都会被当作块级元素。
- 当属性值为 relative 或 sticky 时,元素性质不会改变,内联元素仍然是内联元素,块级元素仍然是块级元素。
z-index
- 只有当 position 属性值为 absolute、relative 或 fixed 时,z-index 属性才会生效。
- z-index 属性值大的元素会覆盖在值小的元素之上,即值越大离用户越近。当两个元素的 z-index 值相同时,在 DOM 树中后出现的元素会覆盖先出现的元素。
position 示例
本示例 html 代码如下:
<div class="container">
<div class="help-div"></div>
<div class="common-position-style ***-position-style"></div>
</div>
基础 CSS 如下:
/* 容器为一个相对定位元素,向下和向右均偏移 100px */
.container {
position: relative;
top: 100px;
left: 100px;
width: 600px;
height: 400px;
background-color: dimgrey;
}
/* 辅助 div 元素,宽 300px,高 200px */
.help-div {
width: 300px;
height: 200px;
box-sizing: border-box;
border: 3px solid blueviolet;
}
/* 被操作 div 中的基础 CSS 属性,宽 300px,高 200px */
.common-position-style {
width: 300px;
height: 200px;
box-sizing: border-box;
border: 3px solid yellow;
background-color: yellowgreen;
}
static
CSS
.static-position-style {
position: static;
left: 50px;
top: 50px;
}
效果图
解析
如上图,设置 static 效果与正常文档流效果一致。left 和 top 值在这里没有效果。
absolute
CSS
.absolute-position-style {
position: absolute;
left: 50px;
top: 50px;
}
效果图
解析
如上图,元素被绝对定位,相对于其父容器(这里其父容器为相对定位)向下和向右偏移 50px。
fixed
CSS
.fixed-position-style {
position: fixed;
left: 50px;
top: 50px;
}
效果图
解析
如上图,元素被固定定位,相对于浏览器窗口向下和向右偏移 50px。注意这里和 absolute 的区别(参照物不一样)。
relative
CSS
.relative-position-style {
position: relative;
left: 50px;
top: 50px;
}
效果图
解析
如上图,元素相对于其本应在文档流的位置,向右和向下偏移 50px。注意这里和 absolute、fixed 的区别(参照物不一样)。
sticky 示例
本示例 html 如下:
<div class="container">
<dl>
<dt>A</dt>
<dd>AAA</dd>
<dd>ABA</dd>
<dd>ACA</dd>
</dl>
<dl>
<dt>B</dt>
<dd>BBB</dd>
<dd>BAB</dd>
<dd>BCB</dd>
</dl>
<dl>
<dt>C</dt>
<dd>CCC</dd>
<dd>CAC</dd>
<dd>CBC</dd>
</dl>
<dl>
<dt>D</dt>
<dd>DDD</dd>
<dd>DAD</dd>
<dd>DBD</dd>
</dl>
<dl>
<dt>E</dt>
<dd>EEE</dd>
<dd>EAE</dd>
<dd>EBE</dd>
</dl>
<dl>
<dt>F</dt>
<dd>FFF</dd>
<dd>FAF</dd>
<dd>FBF</dd>
</dl>
</div>
CSS 如下:
body {
margin: 0;
background-color: beige;
}
.container {
position: relative;
top: 100px;
left: 100px;
width: 600px;
height: 400px;
background-color: dimgrey;
overflow-y: scroll;
}
dl {
padding: 12px 12px 0 12px;
}
dt {
color: white;
background-color: darkgray;
font-size: larger;
border: 1px solid lightgray;
padding: 6px;
position: sticky;
top: 10px;
}
dd {
color: seashell;
line-height: 30px;
border-bottom: 1px solid;
margin-left: 6px;
}
效果图
解析
如上图可以看到,随着滚动条的滚动,标题行先是按照正常文档流位置显示,当到达容器顶端一定位置后,会固定住不动;之后随着自身父元素的消失而消失。这就是 sticky 这个属性值带给我们的功能,先滚动,到达一定位置固定住。(之前被面试,问到这个 sticky 这个属性值还一脸懵逼。然后面试官就说怎么实现先滚动,滚动到一定距离固定住这么一个需求,当时只想到了用 JS 实现,但是 JS 实现也是挺麻烦的。有了这个属性之后,打击能力提升 n 倍!)
z-index 示例
本示例 html 代码:
<div class="container">
<div class="z-index-negative-100"></div>
<div class="z-index-auto"></div>
<div class="z-index-100"></div>
<div class="z-index-1000"></div>
</div>
CSS 代码:
body {
margin: 0;
background-color: beige;
}
.container {
position: relative;
top: 100px;
left: 100px;
width: 600px;
height: 400px;
background-color: dimgrey;
}
.container > div {
width: 300px;
height: 200px;
box-sizing: border-box;
position: absolute;
}
.z-index-auto {
border: 3px solid yellow;
background-color: yellowgreen;
}
.z-index-negative-100 {
left: 50px;
top: 50px;
z-index: -100;
border: 3px solid blue;
background-color: lightblue;
}
.z-index-100 {
left: 100px;
top: 100px;
z-index: 100;
border: 3px solid red;
background-color: lightcoral;
}
.z-index-1000 {
left: 150px;
top: 150px;
z-index: 1000;
border: 3px solid green;
background-color: lightgreen;
}
效果图
解析
如上图,可以看到 z-index 值最大的元素,显示在最上层。即值越大,越靠近用户显示。细心地童鞋会发现少了一个元素,是因为此元素 z-index 设置了负值,而其父元素是相对定位,所以此元素显示在了其父元素下方,就看不见了。