当前位置:Gxlcms > html代码 > CSSStackingContext里那些鲜为人知的坑_html/css_WEB-ITnose

CSSStackingContext里那些鲜为人知的坑_html/css_WEB-ITnose

时间:2021-07-01 10:21:17 帮助过:22人阅读

通常我们在学习/了解CSS的时候,并不会直接接触/了解到stacking context的规则,甚至在初学的时,仅仅接触到z-index、知道可以通过z-index控制元素显示的前后顺序,却常常由此碰到各式各样匪夷所思的bug,这两天我也趟了一次z-index浑水,搞明白了z-index扯出的这一系列stacking context坑。

什么是z-index

在W3C document里对z-index的解释是:

The z-index attribute lets you adjust the order of the layering of objects when rendering content.
It means that CSS style rules allow you to position boxes on layers in addition to the normal rendering layer (layer 0). The Z position of each layer is expressed as an integer representing the stacking order for rendering. Greater numbers mean closer to the observer.

简言之我们通过z-index在layer 0上控制「已定位」元素的先后顺序,其值越大元素越靠近用户。#这里layer 0指代root节点即html元素

什么是Stacking Context

显然仅仅知道z-index的作用并不能解释现实中诸多怪异的CSS z-index定位表现,如同上一节中提到指代root节点的layer 0,在CSS中也可构造出与其相似的结构,这种提供z-index栈空间特性并影响子元素渲染顺序的结构,我们称之为stacking context。

怎样的CSS属性可以使element形成一个Stacking Context

满足下面规则的元素将会构造出一个 Stacking Context 结构:

  • root元素(html)
  • 「已定位」元素(position: absolute or relative)且 指定z-index值非auto的元素
  • flex item且指定z-index值非auto的元素
  • opacity小于1的元素
  • 指定transform值非none的元素
  • 指定mix-blend-mode值非normal的元素
  • 指定filter值非none的元素
  • 指定isolation值为isolate的元素
  • ==特例 mobile webkit & chrome 22+, 指定position: fixed的元素==
  • 在will-change属性上指定值为上述列表任意属性的元素
  • 指定-webkit-overflow-scrolling值为touch的元素

*注意除了前两条之外有如此多满足创建stacking context的条件,这也是造成诸多bug的源泉,比如opacity<1

Stacking Context有什么特性

  • stacking context可以嵌套
  • 每个stacking context相对于兄弟元素是完全独立的,其内部规则不会影响到外部
  • 每个stacking context元素都会被父stacking context当做一个元素施加stacking规则
  • 对于一个stacking context内部的元素,如果这个元素没有形成stacking context,其z-index值是auto(但其实如果这个元素没有形成stacking context,z-index属性对这个元素的表现根本没有意义,我们可以理解为这个元素和其parent stacking context是一体的)。

    我们通过给已定位元素(position: absolute or relative)指定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

    非「定位」元素Stacking Context的特殊规则

    先上一段极其容易产生困惑的代码(不支持embedded scripts略卵疼):

    See the Pen yNJRKX by abruzzi (@abruzzi) on CodePen.