关于z-index的一些事

一般z-index失效基本上都是不了解z-index是如何工作导致的(这没有看这篇blog之前,至少我也是这样的)。它不复杂,但如果不花时间去查看z-index文档,可能会不了解一些关键技术点。

不信?能否解答如下问题,作为检验你是否真正了解z-index

问题:

HTML结构如下:

1
2
3
4
5
6
7
8
9
<div>
<span class="red">Red</span>
</div>
<div>
<span class="green">Green</span>
</div>
<div>
<span class="blue">Blue</span>
</div>

CSS如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
.red, .green, .blue {
position: absolute;
}
.red {
background: red;
z-index: 1;
}
.green {
background: green;
}
.blue {
background: blue;
}

如何将“红色块”放置“绿色块”之后,需要满足如下条件:

  • 不能修改html结构
  • 不能修改任何元素的z-index属性
  • 不能修改任何元素的position属性

codepen:

解决方法

给第一个div(即“红色块”的父节点)添加如下样式:

1
2
3
div:first-child {
opacity: .99;
}

或许你会好奇为什么这个opacity会让“红色块”置于“绿色块”之后(当时我看这个答案也是一脸懵逼了😑)。希望下文能解惑你的好奇。

z-index specification

z-index只对positioned元素(即该元素的position不等于默认static外的值)起作用。对应positoned box(positioned元素),z-index主要:

  1. 指定该元素在当前stacking context的stack层级
  2. 该元素是否创建新的stacking context

z-index可以取如下值:

  • (integer)整数:表示当前元素在当前的stacking context的stack层级,并会让当前元素创建一个新的stacking context

  • auto: 表示当前元素在当前的stacking context的stack层级为0,如果该元素不是root元素,就不会创建新的stacking context

stacking order

stacking context可以相互嵌套,每个元素(box)都属于一个stacking context(自包含),每个positoned box在一个stacking context中都有一个整数的stack层级,它表示在同一个stacking context中的z轴方向stack层级位置。stack层级越大在stacking context中的位置越靠前。如果stack层级相同,按其在DOM文档中出现顺序绘制。

stacking context

The stacking context is a three-dimensional conceptualization of HTML elements along an imaginary z-axis relative to the user who is assumed to be facing the viewport or the webpage. HTML elements occupy this space in priority order based on element attributes.——MDN

stacking context的形成条件:

  • 文档根节点(HTML)| Root element of document (HTML).
  • 元素的position属性值为absoluterelative,并且z-index属性为除auto外的值 | Element with a position value “absolute” or “relative” and z-index value other than “auto”.
  • 元素的position属性值为fixedsticky | Element with a position value “fixed” or “sticky” (sticky for all mobile browsers, but not older desktop).
  • 元素是flexbox容器的子元素,带有z-index属性,且值为除auto外的值 | Element that is a child of a flex (flexbox) container, with z-index value other than “auto”.
  • 元素的opcity属性值小于1 | Element with a opacity value less than 1 (See the specification for opacity).
  • 元素的mix-blend-mode属性值为除normal外的值 | Element with a mix-blend-mode value other than “normal”.
  • 元素的如下属性值为除none外的值 | Element with any of the following properties with value other than “none”:
  • 元素的isolation属性值为isolate | Element with a isolation value “isolate”.
  • 元素的-webkit-overflow-scrolling属性值为touch | Element with a -webkit-overflow-scrolling value “touch”.
  • 元素带有will-change属性 | Element with a will-change value specifying any property that would create a stacking context on non-initial value (see this post).

painted order in stacking context

  1. 形成stacking context元素的backgroundborders | the background and borders of the element forming the stacking context.
  2. 负数的stack层级的child stacking context(负数值越大越前) | the child stacking contexts with negative stack levels (most negative first).
  3. 文档流中非inline级、非positioned子节点 | the in-flow, non-inline-level, non-positioned descendants.
  4. 非positioned浮动子节点 | the non-positioned floats.
  5. 文档流中非positioned的inline级子节点(包括inline tables和inline blocks) | the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
  6. stack层级为0的child stacking context和positoned子节点 | the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
  7. stack层级为正整数的child stacking context | the child stacking contexts with positive stack levels (least positive first).

    Example

参考文章:



声明:本资料仅供学习交流,严禁使用于任何商业用途! 如需转载,转载请注明出处。