软键盘遮挡输入框必须分平台、分组件、分容器三重配合:App端需在pages.json页面style下配softinputMode:"adjustResize"(安卓触发重排、iOS兜底),原生input/textarea须成对设adjust-position和cursor-spacing(80–120),u-input等封装组件不透传;H5/小程序无效该配置,须用resize/pageScrollTo监听+手动滚动;web-view需单独处理,内部H5自行适配。

直接说结论:软键盘遮挡输入框不是单一配置能解决的,必须分平台、分组件、分容器三重配合。iOS 和 Android 行为根本不同,web-view 里和原生页面里处理方式也完全不兼容,硬套一个 cursor-spacing 或监听 uni.onKeyboardHeightChange 必然翻车。
App 端必须配 softinputMode: "adjustResize" 才能触发真实重排
这个配置是 App 端所有上推逻辑的前提,不是可选项。没它,adjust-position 就是摆设,uni.onKeyboardHeightChange 在安卓上压根不触发。
- 必须写在
pages.json中对应页面的style下,不能塞进"mp-weixin"或全局"app-plus"块里 - 值只能是
"adjustResize","adjustPan"只会平移整个 WebView,fixed 元素跟着飘,底部按钮直接消失 - 改完必须重启 HBuilderX 或重新运行 App,热更新不生效
- 如果页面用了
scroll-view或自定义滚动容器,它可能拦截 resize,导致上推失效
adjust-position 和 cursor-spacing 必须成对出现在原生 input/textarea
这两个属性只对原生标签生效,u-input、uni-data-picker 等封装组件大概率不透传,别指望它们自动转发。
-
adjust-position="true"是开关,不写等于没启动引擎 -
cursor-spacing不是“离顶部距离”,而是“光标到输入框可视区域底部的最小间距”;设太小(如20)推不动,太大(如300)页面猛蹿 - 实测稳定区间是
80–120,全面屏手机上100是较稳妥起点 - iOS 上
position: fixed的父容器会导致上推打折,需配合uni.pageScrollTo补位
H5 和小程序只能靠监听 + 手动滚动,softinputMode 完全无效
H5 和小程序根本不认 pages.json 里的 softinputMode,也不能用 cursor-spacing。必须走事件驱动 + CSS 布局兜底。
- H5 端监听
window.addEventListener('resize'),通过高度差判断键盘是否弹出(注意过滤resize频繁触发) - 小程序端依赖
bindfocus和bindblur,配合uni.createSelectorQuery()获取输入框位置,再调用uni.pageScrollTo - 手动滚动时,不能直接改
bottom或transform,要确保父容器支持 flex 布局或position: fixed,否则撑不开 - 多个输入框共用一个滚动逻辑时,每次 focus 要清掉上一次的定时器和偏移量,避免叠加错位
web-view 里的输入框必须单独处理
web-view 是独立浏览器内核,adjust-position 和 cursor-spacing 对它完全无效。它的键盘行为由内部 H5 页面自己控制,uni-app 层只能提供容器适配。
-
pages.json中仍需为该页面配"softinputMode": "adjustResize",否则 web-view 容器高度不会压缩 -
web-view的height不能写死,建议用flex: 1或height: 100vh,并配合overflow-y: auto - 内部 H5 页面需自行监听
resize或使用visualViewportAPI 感知键盘高度变化 - 若无法修改内部 H5,可在 uni-app 层加一层遮罩 + 动态
padding-bottom,但体验不如原生方案顺滑
最容易被忽略的是:iOS 上部分输入法(比如百度输入法)或老机型(iOS 14.5)会忽略 adjust-position,而安卓某些 ROM 根本不发键盘高度事件——所以三端兜底逻辑不能少,监听、属性、CSS 补位得同时存在,缺一不可。


















