position:fixed失效探索

背景

近期遇到一個問題,當使用React Drawer 抽屜時,抽屜中position:fixed不表現爲基於可視窗口定位,而是基於該抽屜進行定位,很好奇這種設定,於是基於該內容進行了一些探索。

探索過程

  1. React Drawer實現方式爲transform
  2. position:fixed的祖先元素爲transform時,定位容器由視口改爲該祖先。
  3. 不僅僅在transform中position:fixed失效,在所有堆疊上下文(Stacking Context)均會導致position:fixed失效。【MDN理論】
  4. 並非所有堆疊上下文(Stacking Context)下position:fixed都失效,僅在:
    • transform 屬性值不爲 none 的元素
    • perspective 值不爲 none 的元素
    • will-change 中指定了任意 CSS 屬性
    • filter 不爲 none
    • 設置了 transform-style: preserve-3d 的元素
  5. 不同瀏覽器的表現也不同,以上五種情況僅在Chrome中表現該特性

堆疊上下文(Stacking Context)

堆疊上下文(Stacking Context):堆疊上下文是 HTML 元素的三維概念,這些 HTML 元素在一條假想的相對於面向(電腦屏幕的)視窗或者網頁的用戶的 z 軸上延伸,HTML 元素依據其自身屬性按照優先級順序佔用層疊上下文的空間。

如何創建堆疊上下文:

  • 根元素 (HTML)
  • z-index 值不爲 "auto"的 絕對/相對定位,
  • 一個 z-index 值不爲 "auto"的 flex 項目 (flex item),即:父元素 display: flex|inline-flex,
  • opacity 屬性值小於 1 的元素(參考 the specification for opacity),
  • transform 屬性值不爲 "none"的元素,
  • mix-blend-mode 屬性值不爲 "normal"的元素,
  • filter值不爲“none”的元素,
  • perspective值不爲“none”的元素,
  • isolation 屬性被設置爲 "isolate"的元素,
  • position: fixed
  • 在 will-change 中指定了任意 CSS 屬性,即便你沒有直接指定這些屬性的值
  • -webkit-overflow-scrolling 屬性被設置 "touch"的元素

結論

Chrome中問題結論:

在Chrome(Blink內核)中,position:fixed在:

  • 祖先元素爲transform 屬性值不爲 none 的元素
  • perspective 值不爲 none 的元素
  • will-change 中指定了任意 CSS
  • filter 不爲 none
  • 設置了 transform-style: preserve-3d 的元素

情況下,定位容器由視口改爲該祖先。

不同瀏覽器position:fixed表現:

CSS Chrome Safari(Mac) FireFox
z-index 值不爲 "auto"的 絕對/相對定位
一個 z-index 值不爲 "auto"的 flex 項目 (flex item)
opacity 屬性值小於 1 的元素
transform 屬性值不爲 "none"的元素 失效 失效 失效
mix-blend-mode 屬性值不爲 "normal"的元素
filter值不爲“none”的元素 失效 失效
perspective值不爲“none”的元素 失效 失效
isolation 屬性被設置爲 "isolate"的元素
position: fixed
在 will-change 中指定了任意 CSS 屬性 失效 失效
-webkit-overflow-scrolling 屬性被設置 "touch"的元素
設置了 transform-style: preserve-3d 的元素 失效 失效

position:fixed不同表現(在不同瀏覽器中打開) DEMO

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