摘要:大致步驟如下監聽滾動事件,計算目標元素距離視口的距離。距離滿足條件時,創建占位元素,修改目標元素定位方式為。僅僅為了實現這個效果頁面上沒有其他內容大動干戈性價比很低。對癥下藥,讓滾動發生在被誤匹配上的祖先元素內即可恢復。
為什么要寫這篇文章Sticky 也不是新知識點了,寫這篇文章的原因是由于最近在實現效果的過程中,發現我對 Sticky 的理解有偏差,代碼執行結果不如預期。決定寫篇文章重新學習一次。
什么是 StickySticky (MDN 翻譯成粘性效果)是 CSS 屬性 position 中的一個可選值。跟我們用得比較多的 static, fixed,relative,absolute 一樣,用來描述元素的定位方式。
從效果上看,Sticky 像是混合體,頁面滑動到“臨界點”之前表現為 relative, 到達“臨界點”時表現為 fixed。
如何使用
使用 CSS Sticky 只需要兩個條件。
position: sticky; top: 0; // right/bottom/left 任一有效值,甚至可以為負像素值
top:0 意思是當元素滑動到距離視口 0px 時再繼續滑動,元素吸頂。可以在 這里 看效果(試試看修改 top 值)
對比 JS 的實現方案沒有 CSS Sticky 之前,類似的效果都是使用 JS 實現。大致步驟如下:
監聽滾動事件,計算目標元素距離視口的距離。
距離不滿足條件時,按兵不動。
距離滿足條件時,創建占位元素,修改目標元素定位方式為 fixed。
window.addEventListener("scroll", () => {
const rect = elem.getBoundingClientRect();
// 計算目標元素和視口的距離
})
在 npm 上搜 sticky 關鍵字,也有很多優秀的包可以使用。以 react-sticky 為例,滿足條件時會創建 placeholder 元素(防止頁面抖動),同時讓 header 定位為 fixed。
右邊是 Chrome Dev-Tools 的 layers 面板,藍色部分為生成的 placeholder。
兩種方案的火焰圖對比(為了放大效果,我把 cpu 調慢了 6 倍)
使用 CSS Sticky,工作都交給 GPU 了,不占用 JS 主線程的資源,在移動端上異常流暢。
由于需要在 scroll event 回調中不斷調用 getBoundingClientRect,而 getBoundingClientRect 又會觸發頁面重排重繪,稍不留神就掉幀卡頓。僅僅為了實現這個效果(頁面上沒有其他內容)大動干戈性價比很低。
結論是:實現 Sticky 效果,優先選擇 CSS Sticky
理解上的偏差修改例子,用一個 div 把 Sticky Header 包裹起來,發現 Sticky 效果失效了!!!
...
<div class="wrapper">
<header>Sticky Headerheader>
div>
...
根據文檔,Sticky 效果只在 Containing Block 內有效,Containing Block 滑出屏幕時,Stickey Element 也跟著滑走。
修改 wrapper 的高度,看效果。
.wrapper {
height: 100px;
background-color: #e6e6e6;
}
多個 Sticky Element 放在一塊就有了前一個被后一個頂出去的特效,實際上并不是真的被頂出去,而是 Containing Block 把它拖走。
代碼看這里
修改例子中的代碼,給 #root 加上 overflow: auto
#root {
overflow: auto;
}
Sticky 效果再次丟失(overflow 設置為其他非 visible 的有效值也是同樣效果。)
看了很多相關的文檔,我的出來的結論是:
Sticky Element 的 offset 值是依據 nearest scrolling ancestor (距離最近的滾動祖先) 計算的,如果沒有匹配上的祖先元素,則使用視口作為參照物。
問題就出在 overflow-x 或者 overflow-y 其中任一為非 visible 則認為是要找的目標元素,而在滾動窗口的過程中,Sticky Element 和 它找到的目標祖先元素的 offset 值一直沒有改變,所以 Sticky 不起作用。
對癥下藥,讓滾動發生在被“誤匹配”上的祖先元素內即可恢復 Sticky Effect。
#root {
overflow: auto;
height: 100vh;
}
兼容性
算上 prefixed ,當前 css sticky 手機端兼容性達到 94.14%,如果你所做的業務需要照顧剩下 5.86% 的用戶,也可以使用 polyfill 或者 position: fixed 。
相關鏈接
uxdesign.cc/position-st…
codyhouse.co/ds/componen…
medium.com/@elad/css-p…
developer.mozilla.org/zh-CN/docs/…
stackoverflow.com/questions/4…
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/6888.html
摘要:大致步驟如下監聽滾動事件,計算目標元素距離視口的距離。距離滿足條件時,創建占位元素,修改目標元素定位方式為。僅僅為了實現這個效果頁面上沒有其他內容大動干戈性價比很低。對癥下藥,讓滾動發生在被誤匹配上的祖先元素內即可恢復。為什么要寫這篇文章 Sticky 也不是新知識點了,寫這篇文章的原因是由于最近在實現效果的過程中,發現我對 Sticky 的理解有偏差,代碼執行結果不如預期。決定寫篇文章重新...
摘要:不過要是一個簡單的小項目,沒那么多要求的話,純還是能很好的適用的,性能上絕對要比通過滾動監聽強上好多倍,而且引用方便,只要數據生成了就可以直接使用 我們經常在手機上看到通訊錄列表,這類布局一般有兩個顯著的效果 showImg(https://segmentfault.com/img/remote/1460000016709371?w=360&h=640); 首字母吸頂 快速定位 下...
摘要:不過要是一個簡單的小項目,沒那么多要求的話,純還是能很好的適用的,性能上絕對要比通過滾動監聽強上好多倍,而且引用方便,只要數據生成了就可以直接使用 我們經常在手機上看到通訊錄列表,這類布局一般有兩個顯著的效果 showImg(https://segmentfault.com/img/remote/1460000016709371?w=360&h=640); 首字母吸頂 快速定位 下...
摘要:不過要是一個簡單的小項目,沒那么多要求的話,純還是能很好的適用的,性能上絕對要比通過滾動監聽強上好多倍,而且引用方便,只要數據生成了就可以直接使用 我們經常在手機上看到通訊錄列表,這類布局一般有兩個顯著的效果 showImg(https://segmentfault.com/img/remote/1460000016709371?w=360&h=640); 首字母吸頂 快速定位 下...
摘要:怎樣才能讓粘性定位起作用粘性定位有兩個主要部分,粘性元素和粘性容器。這是粘性元素可以浮動的最大區域。最好是在以粘性容器底部為自然位置的元素上使用它。 翻譯:瘋狂的技術宅原文:https://medium.com/@elad/css-... 本文首發微信公眾號:jingchengyideng歡迎關注,每天都給你推送新鮮的前端技術文章 瀏覽器對 CSS粘性定位有著非常好的支持,但很多...
閱讀 3084·2021-11-25 09:43
閱讀 2258·2021-09-07 10:28
閱讀 3571·2021-08-11 11:14
閱讀 2781·2019-08-30 13:49
閱讀 3548·2019-08-29 18:41
閱讀 1167·2019-08-29 11:26
閱讀 1979·2019-08-26 13:23
閱讀 3378·2019-08-26 10:43