关于移动端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 个高效工具类》

相关推荐
wuhen_n4 分钟前
JavaScript内存管理与执行上下文
前端·javascript
Hi_kenyon25 分钟前
理解vue中的ref
前端·javascript·vue.js
落霞的思绪2 小时前
配置React和React-dom为CDN引入
前端·react.js·前端框架
Hacker_Z&Q2 小时前
CSS 笔记2 (属性)
前端·css·笔记
Anastasiozzzz2 小时前
LeetCode Hot100 295. 数据流的中位数 MedianFinder
java·服务器·前端
Exquisite.3 小时前
Nginx
服务器·前端·nginx
打小就很皮...3 小时前
dnd-kit 实现表格拖拽排序
前端·react.js·表格拖拽·dnd-kit
Ulyanov3 小时前
从静态到沉浸:打造惊艳的Web技术发展历程3D时间轴
前端·javascript·html5·gui开发
打小就很皮...3 小时前
React 19 + Vite 6 + SWC 构建优化实践
前端·react.js·vite·swc
Highcharts.js3 小时前
使用Highcharts与React集成 官网文档使用说明
前端·react.js·前端框架·react·highcharts·官方文档