关于移动端100vh的坑和终极解决方案,看这一篇就够了!

你肯定有遇到过这种情况:费尽心血写了个页面,容器设置了height: 100vh,在电脑上看完美无缺,结果到手机上......底部居然被浏览器地址栏或者工具栏给挡掉了!

例子 电脑浏览器

手机浏览器

可以看到顶部被浏览器工具栏给遮挡住了。

当你滚动页面时,浏览器地址栏和底部工具栏会自动隐藏/显示。但100vh取的是包含隐藏地址栏的完整视口高度,而不是当前可见部分的高度。

结果就是:设置了100vh的元素,实际高度会超出屏幕可见区域,底部内容直接被截断。

实例

来看个真实例子。假设你要做个登录页:

html 复制代码
<div class="login-page">
  <div class="login-form">
    <h2>欢迎登录</h2>
    <input type="text" placeholder="用户名">
    <input type="password" placeholder="密码">
    <button>登录</button>
  </div>
</div>
css 复制代码
.login-page {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

电脑上看没问题,但到手机上:

  1. 页面打开时,地址栏可见,登录按钮可能被推到可视区域外
  2. 滚动一下,地址栏隐藏了,页面又突然"跳"一下
  3. 用户体验极其糟糕

用户输完密码找不到登录按钮!

解决方案1:dvh(推荐)

css 复制代码
.login-page {
  height: 100dvh; /* 把vh换成dvh就行 */
}

dvh是CSS新规范,专门解决这个问题的。它会自动根据浏览器界面变化动态调整高度。

现代浏览器基本都支持了。如果担心老设备,可以加个回退:

css 复制代码
.login-page {
  height: 100vh;
  height: 100dvh; /* 优先使用dvh */
}

解决方案2:JavaScript动态计算(备用方案)

如果还需要支持很老的浏览器,可以用JS:

javascript 复制代码
function setRealVH() {
  const vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty('--real-vh', `${vh}px`);
}

// 初始化
setRealVH();

// 窗口变化时重新计算
window.addEventListener('resize', setRealVH);
window.addEventListener('orientationchange', setRealVH);

CSS中这样用:

css 复制代码
.login-page {
  height: calc(var(--real-vh, 1vh) * 100);
}

解决方案3:纯CSS Hack(不推荐但可用)

css 复制代码
.login-page {
  height: 100vh;
  height: -webkit-fill-available; /* 针对WebKit浏览器 */
}

@media (orientation: portrait) {
  .login-page {
    height: 100vh;
    height: -webkit-fill-available;
  }
}

这个方案兼容性一般,但知道一下也没坏处。

建议

  1. 新项目直接用dvh,简单有效
  2. 老项目逐步替换,先从关键页面开始
  3. 重要内容永远不要依赖视口底部,确保即使有遮挡也能滚动看到

总结

移动端100vh的坑确实烦人,但现在有了dvh这个终极解决方案,问题基本解决了。

下次再做全屏布局,记得用100dvh而不是100vh,保你平安无忧。

如果这篇文章帮你省了几个小时的调试时间,帮我点个爱心吧~

我是大华,专注分享前后端开发的实战笔记。关注我,少走弯路,一起进步!

📌往期精彩

《写给小公司前端的 UI 规范:别让页面丑得自己都看不下去》

《只会写 Mapper 就敢说会 MyBatis?面试官:原理都没懂》

《别学23种了!Java项目中最常用的6个设计模式,附案例》

《Vue3+TS设计模式:5个真实场景让你代码更优雅》

《别再手写判空了!SpringBoot 自带的 20 个高效工具类》

相关推荐
Hashan5 小时前
Webpack 核心双引擎:Loader 与 Plugin 详解
前端·webpack
前端端5 小时前
claude code 学习记录
前端
一位搞嵌入式的 genius5 小时前
ES6 核心特性详解:从变量声明到函数参数优化
前端·笔记·学习
JarvanMo5 小时前
Flutter:纯函数与不可变模型
前端
玲小珑5 小时前
LangChain.js 完全开发手册(六)Vector 向量化技术与语义搜索
前端·langchain·ai编程
晓得迷路了5 小时前
栗子前端技术周刊第 97 期 - Viteland:8 月回顾、Redux Toolkit 2.9、Nuxt 4.1...
前端·javascript·nuxt.js
前端双越老师5 小时前
前端开发 AI Agent 智能体,需要掌握哪些知识?
前端·node.js·agent
EndingCoder5 小时前
Electron 安全性最佳实践:防范常见漏洞
前端·javascript·electron·前端框架·node.js·桌面端
学前端搞口饭吃6 小时前
React props的使用
前端·javascript·react.js