一次 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 上被软键盘折磨过,

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

相关推荐
Surmon4 小时前
彻底搞懂大模型 Temperature、Top-p、Top-k 的区别!
前端·人工智能
木斯佳6 小时前
前端八股文面经大全:bilibili生态技术方向二面 (2026-03-25)·面经深度解析
前端·ai·ssd·sse·rag
不会写DN7 小时前
Gin 日志体系详解
前端·javascript·gin
冬夜戏雪7 小时前
实习面经记录(十)
java·前端·javascript
爱学习的程序媛8 小时前
【Web前端】JavaScript设计模式全解析
前端·javascript·设计模式·web
小码哥_常8 小时前
从SharedPreferences到DataStore:Android存储进化之路
前端
老黑9 小时前
开源工具 AIDA:给 AI 辅助开发加一个数据采集层,让 AI 从错误中自动学习(Glama 3A 认证)
前端·react.js·ai·nodejs·cursor·vibe coding·claude code
薛先生_0999 小时前
js学习语法第一天
开发语言·javascript·学习
jessecyj9 小时前
Spring boot整合quartz方法
java·前端·spring boot
苦瓜小生9 小时前
【前端】|【js手撕】经典高频面试题:手写实现function.call、apply、bind
java·前端·javascript