软键盘弹出时输入框被遮挡的典型表现是光标藏在键盘下,根本原因是浏览器视口滚动异常及vh单位失效;应禁用vh布局,改用focus事件配合scrollintoview主动滚动,并注意hybrid容器的兼容性差异。

软键盘弹出时输入框被遮挡的典型表现
页面底部的 <input> 或 <textarea></textarea> 获得焦点后,iOS Safari 和部分 Android 浏览器会滚动视口,但经常滚过头、滚不足,或干脆不滚——结果就是光标藏在键盘底下,用户看不见自己在输什么。
这不是 CSS 能单独解决的问题,但 CSS 配合 JS 的焦点响应是关键干预点。纯用 vh 或 % 布局反而会让问题更糟,因为软键盘弹出会动态改变视口高度,而浏览器对 vh 的计算在键盘弹起时并不同步更新(尤其 iOS)。
避免用 vh 做输入框定位依据
iOS 中软键盘弹出后,100vh 仍按原始屏幕高度计算,不会收缩;Android 行为更混乱,有的缩、有的不缩。用它做输入框的 bottom 或 margin-bottom 会导致定位漂移。
- 别写
bottom: calc(100vh - 50px)这类依赖固定视口高度的定位 - 别用
height: 100vh包裹整个表单容器——键盘一出,内容就被截断 - 真正可靠的基准是视口内可滚动区域:用
document.documentElement.scrollHeight或监听resize+focus组合判断
用 scrollIntoView + focus 事件主动滚动
比起靠 CSS “猜”位置,让输入框在获得焦点时主动滚动到可视区更可靠。注意不是所有浏览器都支持 scrollIntoView({ block: 'nearest' }) 的平滑行为,且 iOS 上需配合 setTimeout 防止被键盘动画抢帧。
- 监听
input或textarea的focus事件 - 加
setTimeout(() => el.scrollIntoView({ block: 'nearest', inline: 'start' }), 100),iOS 下这个延迟很关键 - 如果父容器有
overflow: hidden或transform,scrollIntoView可能失效,需确保滚动上下文正确 - Android Chrome 有时需要额外触发
window.scrollTo(0, 0)再滚动,否则初始偏移不准
必要时用 env(safe-area-inset-bottom) 微调底部留白
仅当输入框固定在底部(如聊天输入栏),且你已确保它不会被键盘覆盖时,才用这个 CSS 环境变量补安全区。它不解决遮挡,只防“贴底溢出”。
- 写法是
padding-bottom: env(safe-area-inset-bottom)或margin-bottom: env(safe-area-inset-bottom) - 仅在支持环境变量的系统生效(iOS 11.2+、Android 10+ 部分 WebView),老版本会忽略,需降级 fallback
- 别把它当成键盘高度代理——
env(safe-area-inset-bottom)是刘海/圆角/Home Indicator 高度,和软键盘无关
真正难处理的是 hybrid 容器(比如微信内置浏览器、某些 App WebView),它们对 resize、focus、scroll 事件的触发时机和顺序各不相同,得逐个适配。别指望一套 CSS 规则通吃。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











