原生应用的键盘感知布局会保证:软键盘弹出时,当前输入框自动滚入视野,没有任何东西被遮住。可到了 WebView 里,这份保证没了。WebView 在输入法(IME)出现时不会独立缩放可视视口;页面看不到键盘的几何信息;在 Android 与 iOS 上,用户正在输入的输入框常常被遮住。登录与支付表单变成了盲盒。宿主自有 runtime 提供键盘感知桥——宿主把输入法矩形报告给页面,让当前输入框始终可见。

WebView 看不到键盘

在 Android 上,Chrome 108+ 改变了键盘处理方式:浏览器只缩放可视视口、保持布局不变(resizes-visual)。但 WebView 被明确排除在这次改动之外。Chromium 一个至今未关闭的缺陷报告(issue 40287394)确认:WebView「无法让可视视口独立于布局视口缩放」,而且 Virtual Keyboard API 在 WebView 里根本不工作——boundingRect 被清零、geometrychange 事件从不触发。于是,adjustResize 会让整个布局跳动;adjustPan 会把布局上移但顶部被裁掉;而页面对键盘在哪儿毫无可靠信号。

iOS 同样把输入框藏起来

在 iOS 上,WKWebView 不会在键盘出现时自动把当前输入框滚入视野,而 visualViewport API 在不同版本间表现不一致。结果一样:用户正在输入的输入框落在键盘背后,页面既看不到键盘的尺寸与位置,也就无从把它推到前面。

输入框被遮住时,什么会崩

  • 登录静默失败。 密码框被键盘挡住,用户盲打、提交错误凭证。
  • 支付卡住。 卡号与验证码输入框被遮,结账流程走不下去。
  • 布局跳动。 adjustResize 让整页回流,sticky 与 fixed 元素错乱。
  • 版本轮盘赌。 WebView 139+ 现在会在键盘弹出时缩放可视视口——但实测 resize 事件会清掉输入框焦点、再次隐藏键盘。
  • 没有一致 API。 dvh 单位只在较新引擎上有效;老 WebView 仍把键盘区域算进 100vh。

runtime 解法

宿主自有 runtime 接管键盘。宿主在原生层监听 IME 的显示/隐藏,算出键盘矩形,把它作为键盘 inset 信号桥接给页面。页面随后把当前输入框保持在可见区域内——滚入视野或依据 inset 驱动布局——而不依赖引擎那不可靠的缩放。一套行为,覆盖每台设备、每个系统版本。

维度WebView宿主自有 runtime
键盘几何信息页面不可见桥接报告 IME 矩形
可视视口缩放不独立(Android)宿主驱动,一致
iOS 输入框不自动滚动宿主滚入视野
adjustResize 副作用布局跳动无——inset 感知
跨版本行为随 WebView 版本崩稳定
输入焦点某些缩放下丢失保留

原生应用绝不会让键盘吞掉输入框。原生 WebView 经常如此。runtime 把键盘放到页面看得见的地方——也让输入框回到用户看得见的地方。

参考来源