堆叠上下文与堆叠层级
基本定义
- 堆叠上下文是HTML元素的三维概念,HTML元素在沿垂直于窗口的z轴延伸,HTML元素依据其自身属性按照优先级顺序占用层叠上下文的空间。
- 每个盒都属于一个堆叠上下文。在所属堆叠上下文中,每个定位元素都拥有堆叠层级。堆叠层级决定了元素在z轴上的位置,一般地,堆叠层级越高,元素在z轴上的位置越高(即离窗口越近,覆盖其它元素)。
堆叠层级 z-index
z-index 属性:
属性 | 取值 |
---|---|
可选值 | auto/ 整型数/ inherit |
默认值 | auto |
适用元素 | 定位元素(absolute, fixed, relative) |
可继承性 | 否 |
取值含义:
取值 | 含义 |
---|---|
auto | 生成盒在当前堆叠上下文中的堆叠层级为0。该盒不会建立新的堆叠上下文,除非它是根元素 |
整型数 | 该整数是生成盒在当前堆叠上下文中的堆叠层级,该盒还会建立一个新的堆叠上下文 |
堆叠上下文生成
- 可以生成新堆叠上下文的元素:html根元素,z-index不为auto的定位元素,opacity不为1的元素等。除opacity,CSS3中还有一些特性将导致新堆叠上下文的形成,在此不一一列举了。
上下文与层级的性质
- 堆叠上下文可以包含堆叠上下文,就像一个牌堆上可以垒起新牌堆;
- 堆叠上下文是独立的,任何元素仅属于其所在的唯一层叠上下文,就像一张卡牌只能属于一组牌堆一样;
- 同一上下文中,堆叠层级相同的盒按照文档树顺序从下向上堆叠,即后渲染的元素覆盖之前的元素。
示例:
<div class="s1">前</div>
<div class="s2">后</div></div>
div{
position: absolute;
width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
background: rgb(128, 202, 221);
}
- 每个元素的堆叠层级仅在其所在堆叠上下文有效。举例:若牌堆B在牌堆A上,牌堆A中堆叠层级为100的卡牌仍在牌堆B的所有卡牌之下,包括堆叠层级为负的卡牌。
示例:
在上例的基础上,为所有div添加z-index,以建立新的堆叠上下文。在被覆盖的s1中有一个z-index为100的元素,实际渲染后,它与其父元素s1仍被s2的堆叠上下文覆盖。
div {
position: absolute;
width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
background: rgb(128, 202, 221);
z-index: 0
}
.pre{
z-index: 100;
}
<div class="s1"><div class="pre">我也想在上面</div></div>
<div class="s2"><div>我还是在上面</div></div>
堆叠优先级规则
在每个堆叠上下文中,下列层按从下向上的顺序绘制如下:
- 注1:处于最下方背景和边框指的是层叠上下文根节点的background和border,其内容按照相应规则决定层叠顺序。
- 注2: 第六层中与z-index:0或auto同级的还包含opacity不为0的元素,即其生成的上下文。若不对透明元素进行定位,则z-index无法改变其层叠等级。
- 注3: 若定位元素的z-index为auto,则其不生成新的上下文,其子元素仍参加现有的层叠上下文。
图源:
小火柴的蓝色幻想
实例如下:
注:
本案例中,正index的元素生成的新上下文中有一个z-index为-9的元素,因为层叠上下文的独立性,它仍然处在上下文外其它元素的上方。
* {
padding: 0;
margin: 0;
}
.container {
text-align: right;
opacity: 0.9;
margin: 200px;
position: relative;
height: 550px;
width: 550px;
background: rgb(52, 211, 52);
color: rgb(73, 65, 46)
}
.negativeIndex {
height: 420px;
width: 420px;
top: 0px;
background: rgb(218, 218, 55);
position: absolute;
z-index: -1
}
.block {
/* opacity: 0.9; */
/* position: absolute; */
height: 350px;
width: 350px;
background: rgb(221, 150, 150);
/* z-index:1; */
}
.fl {
height: 250px;
width: 250px;
background: rgb(226, 192, 127);
float: left;
}
.opc {
height: 200px;
width: 200px;
opacity: 0.5;
background:slateblue;
color: white;
position: absolute;
top:0;
}
.postiveIndex {
height: 100px;
width: 100px;
top: -350px;
background: yellowgreen;
position: relative;
z-index: 1;
}
.neo {
text-align: left;
height: 50px;
width: 90px;
border: dotted;
position: absolute;
z-index: -100
}
p {
text-align: right;
position: absolute;
top: 0;
width: 100%;
}
<div class="container">
<div class="fl">浮动</div>
<div class="block"><span>非定位元素</span></div>
<div class="negativeIndex">负 index</div>
<div class="opc">透明元素</div>
<div class="postiveIndex">正 index <div class="neo">z-index: -9</div>
</div>
<p>层叠上下文根节点</p>
</div>