Css Stacking Context

最近写了一个静态页面的时候,出现了一个不常见bug,布局在safari下会出现错乱,但是在firefox、chrome、甚至低版本的IE下都是正常的。仔细排查之后才发现原来是一个弹窗modal的z-index影响的,该弹窗css设置如下:

.dialog{
    position: fixed;
    z-index: -1;
    top: 50%;
    left: 50%;
    overflow: hidden;
    opacity: 0;
    filter:alpha(opacity=0);
    transition: all 300ms ease-in;
    -moz-transition: all 300ms ease-in;
    -webkit-transition: all 300ms ease-in;
    -o-transition: all 300ms ease-in;
    transform: scale3d(0.3, 0.3, 0.3);
    -moz-transform: scale3d(0.3, 0.3, 0.3);
    -webkit-transform: scale3d(0.3, 0.3, 0.3);
    -o-transform: scale3d(0.3, 0.3, 0.3);
    background: #fff;
    box-shadow: 0px 0px 7px rgb( 0, 0, 0 );
    border:1px solid rgb( 221, 221, 221 );
    border-radius: 4px;
}

然后把z-index:-1;修改成z-index:0;之后就正常了。网上搜索了一下,才发现是Stacking Context这个影响的。

Css Stacking Context

——以下为翻译部分(https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
The stacking context是HTML元素的三维概念化的一个虚拟Z轴,它是与用户相对的视口或网页。HTML元素的堆叠优先级顺序是依赖元素的自身属性的。
给定位元素添加z-index,那么这些元素的堆叠顺序将会由z-index的值决定,这是因为这些元素具有了特殊的属性使它们形成了一个 stacking context。
在一个document的任何地方,任何元素都是可以形成stacking context。如下这些属性或元素将会形成一个stacking context。

  • the root element (HTML),
  • 定位元素(absolute、relative)的z-index值不是auto,
  • 采用Flex布局的元素,Flex容器的所有子元素的z-index值不是auto,并且这个Flex容器的display: flex|inline-flex;的时候,
  • 元素的opacity的值小于1的时候,
  • 元素的transform的值不为none的时候,
  • 元素的 mix-blend-mode的值不为normal的时候,
  • 元素的filter的值不为none的时候,
  • 元素的 perspective的值不为none的时候,
  • 元素的isolation值为isolate的时候,
  • 元素的定位为position:fixed;
  • 元素的 -webkit-overflow-scrolling 值为 “touch”的时候。

    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

如果一个元素不是通过「定位」(position: absolute or relative)实现了stacking context,它将会以z-index: 0(高于auto)被看待,因此无论如何更改非「定位」元素的z-index都是无效的。

虽然文档中只提到opacity less 1构成的stacking context被看做z-index: 0,但通过测试,可以发现其他非「定位」方式创建的stacking context拥有与opacity less 1一致的表现。
参考文章:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
https://segmentfault.com/a/1190000002783265

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章