別再用 100vh 了!移動(dòng)端視口高度的終極解決方案
很多同學(xué)一看,so easy,直接 100vh 搞定。
.fullscreen {
height: 100vh;
width: 100%;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
font-size: 68px;
background-color: #333;
}電腦上一測(cè)試 “穩(wěn)得很”。
圖片
但是、但是 等到真機(jī)運(yùn)行的時(shí)候,就突然出現(xiàn)了一個(gè)非常煩人的 滾動(dòng)條,類似這樣。
圖片
很多同學(xué)這就懵了,100vh 不正好就是整個(gè)屏幕的高度嗎?怎么會(huì)超出一塊呢?
如果,你也有這樣的疑惑,那么 恭喜你。看完這篇文章,你就不會(huì)再有這樣的疑惑啦。
1. 問(wèn)題根源:移動(dòng)端的動(dòng)態(tài)視口
先復(fù)習(xí)下概念::1vh = 視口高度的 1%。
在 PC 端,視口高度是完全穩(wěn)定的,工具欄區(qū)域并不會(huì)占據(jù)內(nèi)容區(qū)高度。
圖片
所以 100vh 沒(méi)問(wèn)題。
但在手機(jī)端就不一樣了,瀏覽器的 地址欄和底部工具欄會(huì)動(dòng)態(tài)顯示/隱藏。
- 頁(yè)面剛加載:地址欄、工具欄都在 → 實(shí)際可見(jiàn)區(qū)域變小。
- 頁(yè)面滾動(dòng):UI 收縮甚至消失 → 可見(jiàn)區(qū)域變大。
重要的是:大部分移動(dòng)瀏覽器把 100vh 定義為 工具欄收起后的最大高度。
所以剛加載頁(yè)面時(shí),100vh 實(shí)際比屏幕可見(jiàn)區(qū)域高 → 滾動(dòng)條就冒出來(lái)了。
圖片
2. 過(guò)去的處理方式:JS 動(dòng)態(tài)計(jì)算
以前處理這種問(wèn)題的常見(jiàn)做法是:用 JS 來(lái)算真實(shí)高度。
function setRealVH() {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty("--vh", `${vh}px`);
}
window.addEventListener("load", setRealVH);
window.addEventListener("resize", setRealVH);然后在 CSS 里寫(xiě):
.fullscreen-element {
height: calc(var(--vh, 1vh) * 100);
}雖然能解決,但有幾個(gè)硬傷:
- 性能問(wèn)題:監(jiān)聽(tīng)
resize太頻繁會(huì)掉幀 - 優(yōu)雅度差:純樣式問(wèn)題要靠 JS 打補(bǔ)丁
- 閃爍風(fēng)險(xiǎn):執(zhí)行時(shí)機(jī)沒(méi)把握好,頁(yè)面就會(huì)閃一下
所以說(shuō),這個(gè)方案更多是個(gè)“權(quán)宜之計(jì)”,不好用!
3. 終極解決方案:CSS 動(dòng)態(tài)視口單位
那么終極方案是什么呢?
直接使用 svh 單位
svh→ 小視口高度(工具欄完全展開(kāi)時(shí))lvh→ 大視口高度(工具欄完全隱藏時(shí),等同舊的 100vh)dvh→ 動(dòng)態(tài)視口高度(會(huì)隨著工具欄的出現(xiàn)/消失而自動(dòng)變化 ? 推薦!)
代碼非常簡(jiǎn)單:
.fullscreen {
height: 100dvh; /* 動(dòng)態(tài)填滿可見(jiàn)區(qū)域 */
}效果很完美:
地址欄收起時(shí),元素高度自動(dòng)增大;地址欄出現(xiàn)時(shí),自動(dòng)減小,整個(gè)過(guò)程平滑自然。
4. 兼容性如何?
很多同學(xué)可能會(huì)擔(dān)心兼容性問(wèn)題哈,這個(gè)不用太過(guò)于擔(dān)心。
首先是 國(guó)內(nèi)的手機(jī)系統(tǒng)更新速度都比較快。
同時(shí),從 2023 年起,Safari、Chrome、Edge、Firefox 都已經(jīng)支持了。
圖片
除非你還要兼容非常古老的瀏覽器,否則可以放心上生產(chǎn)啦。































