z-index的一些领悟
一、概念
1.什么是z-index?
z-index属性设置元素的堆叠顺序,适用于已经定位的元素(即position:relative/absolute/fixed)。
通过z-index在layer 0上控制「已定位」元素的先后顺序,其值越大元素越靠近用户。#这里layer 0指代root节点即html元素。
2.什么是 Stacking Context ?
翻译就是“堆叠上下文”。每个元素仅属于一个堆叠上下文,元素的z-index描述元素在相同堆叠上下文中“z轴”的呈现顺序。
就像上面提到指代root节点的layer 0,在CSS中也可以构造出与其相似的结构,这种提供z-index栈空间特性并影响子元素渲染顺序的结构,我们称之为stacking context。可以理解为是一个作用域。
3.z-index的取值:
默认值:auto,当一个元素新生成时,他默认的z-index为auto,他不会自己产生一个新的local stacking context,所以会处于和父box相同的堆叠上下文中;
正负整数:这个整数就是当前元素的z-index值,z-index值为0也会生成一个local stacking context。
二、使 element 形成一个 Stackigng Content 的条件
满足以下规则的元素都将构造一个Stackigng Content 结构:
- 1.root元素(html);
- 2.已定位元素,且指定z-index值非auto的元素;
- 3.flex item且指定z-index值非auto的元素;
- 4.opacity小于1的元素;
- 5.指定transform值非none的元素;
- 6.指定mix-blend-mode值非normal的元素;
- 7.指定filter值非none的元素;
- 8.指定isolation值为isolate的元素;
- 9.==特例 mobile webkit & chrome 22+, 指定position: fixed的元素==;
- 10.在will-change属性上指定值为上述列表任意属性的元素;
- 11.指定-webkit-overflow-scrolling值为touch的元素。
除1.2外,其余规则均摘抄自网上资料,需验证使用,并注意造成bug的隐患。
非定位元素 Stackigng Content 的特殊规则:
如果一个元素不是通过「定位」(position: absolute or relative)实现了stacking context,它将会以z-index: 0(高于auto)被看待,因此无论如何更改非「定位」元素的z-index都是无效的。
三、Stackigng Content 的特性
- 1.stacking context可以嵌套;
- 2.每个stacking context相对于兄弟元素是完全独立的,其内部规则不会影响到外部;
- 3.每个stacking context元素都会被父stacking context当做一个元素施加stacking规则;
stacking context内部的元素如果没有形成stacking context,这个元素的z-index值是auto(但其实如果这个元素没有形成stacking context,z-index属性对这个元素的表现根本没有意义,我们可以理解为这个元素和其parent stacking context是一体的)。
我们通过给已定位元素指定z-index值,以改变这个元素在其parent stacking context中Z轴的「相对偏移」量。这里的「相对偏移」指的是以parent stacking context为基准,相对于其它兄弟元素距离用户远近的顺序。
对于形成stacking context的元素,由于他的z-index属性并不对内部元素产生影响,因此这个元素的子元素以这个元素(parent stacking context)为z-index相对基准点即z-index: auto,这些子元素的stacking context兄弟元素按照下面的远近顺序展示在屏幕:
parent stacking context >> z-index < 0 >> 非stacking context元素(z-index: auto) >> z-index >= 0
*注意在stacking context中的元素不会远于parent stacking context
PS:即使子元素的z-index值远远的小于其父元素的兄弟元素的z-index值,他也会在其父元素的兄弟元素之上显示。
渲染的时候,先确定小的stacking context中的顺序,一个小的stacking context确定了以后再将其放在父stacking context中堆叠。有种由内而外,由小及大的感觉
四、其他一些堆叠顺序
1.不使用z-index时的堆叠顺序(即默认情况):
根元素(即HTML元素)的background和borders;
正常流中非定位后代元素(这些元素顺序按照HTML文档出现顺序);----正常流中非定位元素,总是先于定位元素渲染,所以表现就是在定位元素下方,跟它在HTML中出现的顺序无关;
已定位后代元素(这些元素顺序按照HTML文档出现顺序);----没有指定z-index值的定位元素,他们的堆叠顺序取决于在HTML文档中的顺序,越靠后出现的元素,位置越高,和position属性无关。
2.浮动堆叠顺序:
浮动元素z-index位置介于非定位元素和定位元素之间。
根元素(即HTML元素)的背景和border;
正常流中非定位后代元素(这些元素顺序按照HTML文档出现顺序);
浮动元素(浮动元素之间是不会出现z-index重叠的);
正常流中inline后代元素;
已定位后代元素(这些元素顺序按照HTML文档出现顺序)。
3.z-index对堆叠顺序控制的示意图:
- Root:z-index值为默认auto,即0
- parent stacking context 1:z-index=1
- stacking context:z-index=1,其父元素z-index值 1,所以最终值为1.1
- stacking context:z-index=2,其父元素z-index值 1,所以最终值为1.2
- stacking context:z-index=-2,其父元素z-index值 1,所以最终值为1.-2
- parent stacking context 2:z-index=2
- parent stacking context 1:z-index=1
五、使用z-index的小技巧
尽量避免给z-index使用负值。当然不是绝对的,比如在做图文替换的时候可以使用负值。
为避免不同的stacking context 赋值相同的z-index,或者不同的stacking context随意赋值z-index大小的值,使z-index值太过混乱,可以划分父stacking context 的z-index值得区域,比如[0--100],[101--200],[201--300],第一个父stacking context下的子stacking context同样划分区域,如[0-10],[11-20]......以此类推。

浙公网安备 33010602011771号