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

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