探究 position-sticky 失效問題

CSS 的 position 值中,有一個很是有用的值 -- position: sticky,一般會被用於各類吸頂,吸底,吸邊的效果中。css

若是你對 sticky 還不太熟悉,能夠先看看個人這篇文章:使用 position:sticky 實現粘性佈局,固然,這篇文章裏面有稍微探討 position: sticky 生效或者說失效的規則,可是不太充分。html

最近遇到一些 position-sticky 失效的場景,因此總結了一下。git

 

position-sticky 生效的原理

在 W3 官方文檔中的定義是:Sticky positioning is similar to relative positioning except the offsets are automatically calculated in reference to the nearest scrollport.github

轉換成通俗的大白話就是,Sticky 定位相似於相對定位,(當它表現爲 fixed 定位的特性時)會根據最近的滾動容器(nearest scrollport)自動計算偏移量。佈局

其中有一個很是重要的概念就是 nearest scrollport,它表示 sticky 元素在即將消失前會相對它最近的 scrollport 去作定位。 url

 

正常的 DEMO

因此正常而言,相似下面的這種狀況,sticky 是能夠正常展現的。spa

<div class="container"> - 可滾動的容器 scrollport     
    <div class="sticky">   - 設置了 sticky 的元素

CodePen Demo -- Normal Sticky Demo 3d

失效的 position: sticky

一、包裹的父容器高度與 sticky 元素一致

有趣的是,若是在 .sticky 元素和你但願 .sticky 生效吸附的滾動元素中間,添加上一層 .parent 的 div 元素,不給 div 添加任何樣式,sticky 則失效了。rest

譬如是這樣:code

<div class="container">      - 可滾動的容器 scrollport     
    <div class="parent"> 
         <div class="sticky">   - 設置了 sticky 的元素

CodePen Demo -- invalid Sticky Demo 1

失效緣由:此時 .sticky 元素的最近的 scrollport 變成了它的父容器 div,而父容器 div 的高度和 .sticky 元素的高度是同樣的,因此表現不出 fixed 的特性。

其實,這裏不算失效,咱們只須要將包裹 .sticky 元素的父容器的高度設置的大於 .sticky 元素自己,也能看到效果。

譬如,咱們能夠加上

.parent {
    height: 100vh;
}

此時,sticky 將從新生效,像是這樣:

其實,形成這種現象的本質緣由是,設置了 position: sticky 的元素吸附的基準元素從 .container 變成了 .parent 。

 

二、包裹的父容器設置了 overflow: hidden

第二種狀況,也會致使 position: sticky 的 fixed 定位特性失效。也就是 .sticky 元素的祖先容器存在 overflow: hidden。相似這樣

<div class="container">      - 可滾動的容器 scrollport     
    <div class="hidden">      - 設置了 overflow: hidden
         <div class="sticky">   - 設置了 sticky 的元素

CodePen Demo -- invalid Sticky Demo 2

在上面這個 DEMO 裏面,設置了 sticky 的元素的父元素 hidden 元素,它的高度是遠比 stikcy 元素高的,可是滾動的過程當中卻沒有表現出 fixed 的特性。

緣由在於,設置了 overflow: hidden 的元素,它再也不代用滾動的特性,當 sticky元素吸附於.hidden元素的頂部時,它隨着 .hidden` 元素自己在 container 移動。因此,全部的 sticky 元素都會被滾動出 container 的滾動區域。

固然,這裏有一點比較奇怪的是,.sticky 元素相對 .hidden 元素進行 fixed 定位,而不是相對 .container 元素進行 fixed 定位,表面設置了 overflow: hidden 的元素,它也是一個 scrollport。

其實,不止是 overflow: hidden ,設定爲 position: sticky 元素的任意父節點的 overflow 屬性必須是 visible,不然 position:sticky 不會生效。

 

總結一下

看完上面幾個 DEMO,能夠好好總結一下 position:sticky 的生效規則,明白了生效規則就會知道爲何有的時候設定的 sticky 會失效:

  1. 須指定 top, right, bottom 或 left 四個閾值其中之一(且達到設定的閾值),纔可以使粘性定位生效。不然其行爲與相對定位相同;
    • 而且 top 和 bottom 同時設置時,top 生效的優先級高,left 和 right 同時設置時,left 的優先級高
  2. 設定爲 position: sticky 的元素的任意父節點的 overflow 屬性必須是 visible,不然 position:sticky 不會生效;在知足上述狀況下,設定了 position: sticky 的元素的父容器的高度必須大於當前元素,不然也會失效。(固然,此時,sticky 吸附的基準元素就會變成父元素)
    • 若是 position: sticky 元素的任意父節點定位設置爲 position: overflow,則父容器沒法進行滾動,因此 position:sticky 元素也不會有滾動而後固定的狀況
  3. 在知足上述狀況下,設定了 position: sticky 的元素的父容器的高度必須大於當前元素,不然也會失效。(固然,此時,sticky 吸附的基準元素就會變成父元素)

 

最後

好了,本文到此結束。

更多精彩 CSS 技術文章彙總在個人 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。

若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。

相關文章
相關標籤/搜索