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

五、使用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]......以此类推。

 

----以上内容总结整理于 starof 以及 Abruzzi 两位前辈的博客,以及一些自己个人的领悟和实验结果。

posted @ 2016-08-24 23:04  差不多是条咸鱼了  阅读(337)  评论(0)    收藏  举报