關鍵要點
position: sticky
屬性允許導航欄或其他元素在用戶滾動時保持可見,而無需固定在頁面上。此屬性在其父元素內表現得像靜態定位,直到達到給定的偏移閾值,此時它就像值被設置為 fixed
一樣。 position
和 top
屬性的值。但是,當元素的位置更改為 fixed
時,此方法可能會導致問題,從而導致它離開頁面流,並且下方的元素“向上跳躍”。 position: sticky
”屬性的瀏覽器支持有限。但是,有一些 polyfill 可用於提供此功能,包括 Filament Group 的 fixed-sticky、Matthew Phillips 的 position–sticky- 和 Oleg Korsunsky 的 Stickyfill。 如果您閱讀過 Annarita Tranfici 的文章《Obvious Design always wins》,您可能會同意她的說法:
人們期望看到常見的模式:在頁面頂部找到主菜單,在右上角找到搜索框,在底部找到頁腳,等等。
我同意人們期望網站的某些組件放置在特定位置,在我看來,對於主菜單來說,這一點更為重要。
有時,由於客戶的要求或因為我們已經確定這是最佳方法,我們可能需要主導航始終在頁面上可見,而無需將其固定到位,基本上跟隨頁面內容。近年來,許多基於 JavaScript 的解決方案問世,因為僅 CSS 無法完成此任務。
在本文中,我們將討論 position: sticky
,這是解決此問題的新的 CSS 解決方案。
在討論此 position
屬性的新值之前,讓我們更好地理解我們試圖解決的問題。
假設我們精彩網站的主菜單位於標題之後,但仍在頁面頂部(不在側邊欄中),並且佔據所有可用寬度。這可能看起來像這樣:
我們想要實現的是,當用戶滾動頁面時,一旦菜單位於視口頂部,菜單就不會滾動到視圖之外,而是會粘在頂部位置——就像它應用了position: fixed
一樣(僅當它到達視口頂部時)。
要使用傳統代碼實現此目的,我們需要添加一些 JavaScript。我們監聽頁面的滾動事件,並使用 JavaScript 根據視口的當前位置更改 position
和 top
屬性的值。具體來說,當菜單位於視口頂部時,我們需要向菜單添加 top: 0
和 position: fixed
,否則將屬性恢復為其默認值。
另一種類似的方法是在我們的 CSS 中創建一個包含這些值的類,然後根據需要使用 JavaScript 添加和刪除該類,這可能看起來像這樣:
<code class="language-javascript">var menu = document.querySelector('.menu') var menuPosition = menu.getBoundingClientRect().top; window.addEventListener('scroll', function() { if (window.pageYOffset >= menuPosition) { menu.style.position = 'fixed'; menu.style.top = '0px'; } else { menu.style.position = 'static'; menu.style.top = ''; } });</code>
請注意,此代碼段不處理舊版本的 Internet Explorer。如果您需要處理這些瀏覽器(可憐的您!),我將提供一些您可以考慮的 polyfill 選項。
此第二步的實時演示如下所示:
但是等等!你能發現這段代碼引起的問題嗎?我見過的許多實現,包括我們迄今為止開發的實現,都沒有考慮到一個重要的問題。當我們將元素的位置更改為fixed
時,它會離開頁面的流,因此下方的元素會“向上跳躍”大約等於元素高度的像素數(此“跳躍”的高度取決於邊距、邊框等)。
一個可能的解決方案是注入一個與我們想要“粘貼”的元素大小相同的佔位符元素,這樣當我們更新粘性元素的樣式時,就不會發生跳躍。此外,如果已設置正確的值,我們不想無緣無故地反復重新分配值。最後,我們想採用我使用 CSS 類描述的技術。
JavaScript 代碼的最終版本如下所示:
<code class="language-javascript">var menu = document.querySelector('.menu'); var menuPosition = menu.getBoundingClientRect(); var placeholder = document.createElement('div'); placeholder.style.width = menuPosition.width + 'px'; placeholder.style.height = menuPosition.height + 'px'; var isAdded = false; window.addEventListener('scroll', function() { if (window.pageYOffset >= menuPosition.top && !isAdded) { menu.classList.add('sticky'); menu.parentNode.insertBefore(placeholder, menu); isAdded = true; } else if (window.pageYOffset < menuPosition.top && isAdded) { menu.classList.remove('sticky'); menu.parentNode.removeChild(placeholder); isAdded = false; } });</code>
這是 sticky
類的聲明塊:
<code class="language-css">.sticky { top: 0; position: fixed; }</code>
最終結果顯示在此下一個演示中:
現在您已經很好地掌握了問題是什麼以及可能的基於 JavaScript 的解決方案是什麼,是時候擁抱現代化並討論這個 position: sticky
是關於什麼了。
如果您勇敢地仔細閱讀了上一節,您可能想知道“瀏覽器為什麼不能為我做到這一點?”很高興您問!
sticky
是為 CSS position
屬性引入的一個新值。此值應該在其父元素內表現得像 position: static
,直到達到給定的偏移閾值,在這種情況下,它就像值被設置為 fixed
一樣。換句話說,通過使用 position: sticky
,我們可以無需 JavaScript 即可解決上一節中討論的問題。
回顧我們之前的示例並使用此新值,我們可以編寫:
<code class="language-css">.menu { margin: 0; padding: 0; width: 100%; background-color: #bffff3; position: sticky; }</code>
瀏覽器將完成其餘工作!就這麼簡單。
目前對這個新值的支持非常糟糕。以下是每個瀏覽器的堆棧情況:
-webkit
供應商前綴支持該值(即 position: -webkit-sticky
)有關所有詳細信息,請參見 Can I Use… 上的 position: sticky
。
幸運的是,有很多 polyfill 可供選擇:
position: sticky
position: sticky
CodePen 演示(需要 jQuery)以下演示顯示了 position: sticky
的實際效果。如前所述,要使其工作,並且取決於您使用的瀏覽器,您可能需要激活一個標誌。
儘管這項新功能沒有很好的瀏覽器支持,您可能也不願使用 polyfill,但如果使用 Modernizr 定義替代樣式,它將優雅地降級到默認的 position: static
或 position: fixed
。
如果您嘗試過此屬性或知道任何其他 polyfill,請在評論中告訴我們。
CSS position: sticky
是相對定位和固定定位的混合體。它允許元素在其父元素內表現得像相對位置,直到達到給定的滾動點,此時它會變為固定位置。這與其他 CSS 位置不同。例如,“相對”位置允許您相對於元素的正常位置定位元素,而“固定”位置將元素相對於瀏覽器窗口定位,即使頁面滾動它也不會移動。 “絕對”位置將元素相對於最近的已定位祖先定位,“靜態”是默認值,並根據頁面的正常流程定位元素。
您的 CSS position: sticky
不起作用可能有幾個原因。一個常見的原因是父元素的 overflow
屬性設置為 hidden
、auto
或 scroll
。另一個原因可能是粘性元素有一個比它高的同級元素,導致它從視口中滾動出來。此外,請確保粘性元素不是表格元素,因為在某些瀏覽器中,CSS position: sticky
不適用於表格元素。
雖然 CSS position: sticky
在現代瀏覽器中得到廣泛支持,但在某些舊版本中可能不起作用。為了確保跨所有瀏覽器的兼容性,您可以使用 polyfill。 polyfill 是一個提供您期望瀏覽器原生提供的技術的腳本。 CSS position: sticky
的一個流行 polyfill 是 Stickyfill。
是的,您可以將 CSS position: sticky
與其他 CSS 屬性一起使用。例如,您可以將其與 z-index
一起使用來控制堆疊順序,或與 box-shadow
一起使用來在元素變為粘性時創建陰影效果。
當粘性元素位於滾動容器內時,當您向下滾動時,它會粘在容器的頂部,並且當容器的底部邊緣滾動過去時,它將停止粘性。
是的,您可以在元素底部使用 CSS position: sticky
。您只需要為 bottom
屬性指定一個負值即可。這將使元素粘在容器的底部。
邊距與 CSS position: sticky
的工作方式與它們與相對定位一起工作的方式相同。邊距將相對於其粘性位置移動粘性元素,而不是其原始位置。
是的,您可以將 CSS position: sticky
用於水平滾動。您只需要為 left
或 right
屬性指定一個值,而不是 top
或 bottom
屬性。
滾動偏移量由 top
、right
、bottom
和 left
屬性控制。您為這些屬性指定的值決定了元素開始粘貼的視口相應邊緣的距離。
是的,您可以將 CSS position: sticky
與 CSS 過渡一起使用。但是,請記住,過渡僅在元素從相對位置更改為固定位置時才適用,而不是在它粘貼時。
請注意,我已將 CodePen 鏈接替換為佔位符,因為我無法訪問實際的 CodePen 示例。您需要替換這些佔位符為實際的鏈接。 此外,我盡可能地對原文進行了改寫,力求在不改變原意的情況下,使文章更流暢自然。
以上是CSS'位置:粘性” - 介紹和polyfills的詳細內容。更多資訊請關注PHP中文網其他相關文章!