問題描述
在玩了一段時間 position:sticky
之后,我開始為粘性導(dǎo)航實現(xiàn)它,并遇到了這個有趣但令人沮喪的滾動彈跳問題.
After playing with position: sticky
for a while, I started implementing it for sticky navigation and ran into this interesting, but frustrating scroll bouncing issue.
這是在許多網(wǎng)站上常見的導(dǎo)航行為類型,您通常會使用 javascript 來計算頁面中相對元素的偏移量.當元素到達窗口頂部時,將添加一個 'stuck' 類,使用 position: fixed
將該元素從文檔流中取出,并添加一個相同高度的虛擬元素在它的地方,以防止頁面跳躍".此外,通常會看到 javascript 然后縮小導(dǎo)航的高度以在滾動時節(jié)省空間.
This is a common type of navigation behaviour seen on many sites, where you would traditionally use javascript to calculate offsets to a relative element in the page. When the element reaches the top of the window, a 'stuck' class would be added, taking the element out of the document flow with position: fixed
, and a dummy element of the same height would be added in it's place to prevent the page from 'jumping'. Additionally, it's common to see javascript then shrink the height of that navigation to save space while scrolling.
CSS 現(xiàn)在似乎用 position:sticky
處理了所有這些,除了(據(jù)我所知)檢測元素何時卡住".相反,我使用一些 javascript 來進行卡住檢測,發(fā)現(xiàn)一切正常,直到 粘性元素的高度需要更改.
CSS now seemingly takes care of all this with position: sticky
, apart from (as far as I can tell), detecting when the element is 'stuck'. Instead I used some javascript to do the stuck detection, discovering that everything works great, right up until the height of the sticky element needs to change.
這很難解釋,但它會在生產(chǎn)中造成嚴重破壞 - 所以這里有一個簡化的示例,以盡可能簡單地說明這個問題.
It's pretty hard to explain, but it wreaks havoc in production - so here's a stripped down example I've made to illustrate the issue as simply as possible.
CSS 粘貼位置高度調(diào)整錯誤
當頁面的高度恰到好處的長度時最好說明,所以我在元素上設(shè)置了一個固定的高度,以確保每個人都能看到相同的東西.您可以添加更多內(nèi)容,但滾動過去時仍然存在問題.
It's best illustrated when the height of the page is just the right length, so I've set a fixed height on the element to make sure everyone is able to see the same thing. You can add more content and it's still an issue when scrolling past.
結(jié)果是一些非常奇怪的行為.向下滾動時,導(dǎo)航卡住,當它縮小導(dǎo)航欄時,瀏覽器會自動創(chuàng)建由 position:sticky
提供的虛擬元素",似乎保持同步用它.這意味著,當添加卡住的類時,整個頁面變小,幾分之一秒后,導(dǎo)航不再卡住,從而導(dǎo)致故障振動循環(huán).
The result is some really weird behaviour. When scrolling down, the navigation sticks, and as it shrinks the navbar, the 'dummy element' the browser is automatically creating courtesy of position: sticky
seems to be kept in sync with it. That means, when the stuck class is added, the whole page gets smaller, and a fraction of a second later, the navigation is no longer stuck, thus resulting in a glitchy vibration loop.
我測試過的每個瀏覽器的行為也完全不同.在 chrome 中,這種彈跳永遠無法解決,它一直處于無限循環(huán)中,不斷添加/刪除卡住的類.更有趣的是,在 Safari 中,滾動位置被推回"到不會出錯的狀態(tài).然后在 Firefox 中,它會同時執(zhí)行這兩項操作,會出現(xiàn)一兩秒鐘的故障,然后再次強制滾動位置恢復(fù).
The behaviour is also completely different across every browser I've tested. In chrome, this bouncing can never be resolved, it stays in the infinite loop constantly adding / removing the stuck class. More interestingly in Safari, the scroll position is 'pushed back' to a state where it wont bug out. Then in Firefox, it does both of these, glitching for a second or two, before forcing the scroll position back up again.
我想知道是否有人遇到過這種情況并提出任何解決方案?我想出的任何 js 解決方法都沒有真正奏效或非常好!當然,隨著人氣的增長,更多的人會喜歡這個......
I'm wondering if anyone has experienced this, and come up with any solutions? Any js workaround I've come up with hasn't really worked or been very good! Surely as popularity grows, more people are going to hit this one...
歡迎天才的變通方法、技巧、見解或完美的解決方案!
Genius workarounds, hacks, insights, or perfect solutions all welcome!
推薦答案
在應(yīng)用會改變其大小(并可能影響窗口大小)的更改時,嘗試將 overflow-anchor: none;
添加到粘性元素/元素定位).
Try adding overflow-anchor: none;
to the sticky element when applying changes that would alter its size (and potentially affect window size/element positioning).
更新:最終,我找到的正確解決方案是:擁有一個永遠不會改變大小的外部元素(它在任何給定斷點處始終保持相同的全高).那個是粘的.但它也應(yīng)該沒有背景/視覺樣式,并且它的有效高度應(yīng)該由高度 + 底部邊距定義(這樣它就可以在文檔中占用適量的初始空間,但實際上不會在視覺導(dǎo)航后阻止點擊縮小并提供更多空間.
Update: ultimately, the right solution I've hit on is: have an outer element that NEVER changes size (it's always the same full height at any given breakpoint). That one is made sticky. But it also should have no background/visual styles, and it's effective height should be defined by height + bottom margin (so that it takes up the right amount of initial space in the document, but doesn't actually block clicks once the visual nav shrinks and gives more space.
然后有一個內(nèi)部元素會改變大小,無論是在現(xiàn)實中還是在視覺上.
Then have an inner element that does change size, either in reality or just visually.
您還可以使用現(xiàn)代屬性,例如包含:布局大小;像
You can also use modern properties like contain: layout size; on the inner element like
這篇關(guān)于位置:粘性 - 結(jié)合 javascript 高度調(diào)整時滾動彈跳的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!