一次 H5 表单事故:100vh 在 Android 上到底坑在哪

我用 100vh 写的 H5,在 Android 上被软键盘"顶穿"了 😭

事情是这样的。

我用 height: 100vh 写了一个很普通的 H5 页面,

结构也很常规:上面是内容,下面是输入框。

在 iOS 上一切正常,

结果一到 Android,用户一点输入框------

👉 软键盘弹起,输入框直接被挡住。

那一刻我意识到:
又是 100vh 的锅。


问题复现:看起来很合理,其实已经埋雷了 💣

css 复制代码
.page {
  height: 100vh;
  display: flex;
  flex-direction: column;
}
ini 复制代码
<input placeholder="请输入手机号" />

现象是这样的:

  • Android 软键盘弹起

  • 页面视觉高度明显变小

  • 但 .page 仍然是 100vh

  • 👉 输入框被键盘盖住,页面不滚动

用户:看不见怎么输?****

我:......****


深挖原因:不是你代码写错,是

100vh

理解错了 🤯

很多人(包括我以前)都会默认:

vh = 当前可视区域高度

但在 Android 浏览器 / WebView 里,真实情况是:

  • vh 取的是 初始布局视口高度

  • 软键盘弹起:

    • 改变的是"可视区域"

    • 不会重新计算 vh

一句话总结:

键盘变了,vh 没变。

所以你看到的就是:

  • 页面下面被键盘盖住
  • CSS 还以为自己是"满屏"

那些年我试过但不太靠谱的方案 🙃

❌ 方案一:监听

resize

javascript 复制代码
window.addEventListener('resize', () => {
  // 动态改高度
});

问题:

  • 有的 Android 触发,有的不触发
  • WebView 行为更是五花八门
  • 维护成本很高

❌ 方案二:

scrollIntoView

css 复制代码
input.scrollIntoView({ behavior: 'smooth' });

问题:

  • 治标不治本
  • 多输入框体验很怪
  • 页面高度逻辑本身还是错的

正确解法一:用

svh

,让页面"稳住" 🧘‍♂️

arduino 复制代码
.page {
  min-height: 100vh;
  min-height: 100svh;
}

为什么

svh

有用?

  • svh = 最小视口高度****

  • 软键盘弹起时:

    • 可视区域只会变小

    • 页面不会出现"被盖住却不滚"的情况

✅ 不抖

✅ 不需要 JS

✅ 非常适合表单 / 登录 / 支付页


正确解法二:沉浸式场景用

dvh 🎮

css 复制代码
.page {
  height: 100vh;
  height: 100dvh;
}

dvh 的特点是:

  • 视口变,它就变

  • 键盘弹起,页面高度立刻重新计算

适合:

  • 活动页

  • 视频页

  • 对高度变化有心理预期的页面

⚠️ 不太适合关键表单页(容易抖)


100%

能不能救?答案是:不能 🙅‍♂️

css 复制代码
.page {
  height: 100%;
}

原因很简单:

  • 100% 依赖父容器高度

  • 父容器通常还是 100vh

  • 本质问题没有变

一句话点醒自己:

100% 是布局单位,不是视口单位。****


我的最终推荐(直接抄作业 ✍️)

✅ 表单 / 登录 / 支付页

arduino 复制代码
.page {
  min-height: 100vh;
  min-height: 100svh;
}

✅ 沉浸式页面

css 复制代码
.fullscreen {
  height: 100vh;
  height: 100dvh;
}

写在最后

以前我们总想着:

用 JS 去修补浏览器的坑

但现在发现:

CSS 自己已经进化了,只是我们还在用旧认知。****

如果你也在 Android H5 上被软键盘折磨过,

希望这篇能帮你少掉几根头发 🧠✨

相关推荐
知其然亦知其所以然2 小时前
小米的奇幻编程之旅:当 JavaScript 语法变成了一座魔法城
前端·javascript·面试
是一碗螺丝粉2 小时前
突破小程序5层限制:如何用“逻辑物理分离”思维实现无限跳转
前端·架构
Aniugel2 小时前
Vue2怎么搭建前端性能/错误/行为监控体系
vue.js·面试·监控
神秘的猪头2 小时前
🎉 React 的 JSX 语法与组件思想:开启你的前端‘搭积木’之旅(深度对比 Vue 哲学)
前端·vue.js·react.js
三十_2 小时前
如何正确实现圆角渐变边框?为什么 border-radius 对 border-image 不生效?
前端·css
江公望2 小时前
VUE3 data()函数浅谈
前端·javascript·vue.js
江公望2 小时前
VUE3 defineProps 5分钟讲清楚
前端·javascript·vue.js
计算机毕设VX:Fegn08953 小时前
计算机毕业设计|基于Java + vue水果商城系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·课程设计
周杰伦_Jay3 小时前
【 Vue前端技术详细解析】目录结构与数据传递
前端·javascript·vue.js