小程序 input 软键盘与输入框的距离:用 cursor-spacing 与 focus 调优键盘弹起体验
1. 键盘一弹起来输入框就“消失”了微信小程序里做表单最容易被用户吐槽的不是校验逻辑而是点一下输入框软键盘“唰”地弹上来结果输入框被顶到屏幕外面或者贴着键盘边缘只剩一条缝。用户一边打字一边猜自己输的是什么体验直接崩掉。这个问题的核心其实是软键盘弹起后页面可视区域变小而输入框没有跟着上移或者上移的距离不对。微信小程序给input组件提供了几个专门处理这件事的属性cursor-spacing、focus、adjust-position、confirm-hold。它们各自管一件事组合起来才能让键盘和输入框保持一个舒服的距离。我试过在同一个页面里只加cursor-spacing不改adjust-position结果在部分安卓机上输入框还是被遮住一半后来才发现是页面滚动容器和键盘顶起逻辑打架了。这篇内容适合正在做小程序表单、聊天输入框、评论区的开发者。你会看到每个属性到底控制什么、不同机型为什么表现不一样、怎么用真机一步步验证距离是否合适。所有配置片段都可以直接复制到你的wxml里跑起来看效果。2. 先把 TaoToken 的接入准备做掉在调键盘距离之前如果你的小程序里已经接了模型对话、代码补全这类能力建议先把 TaoToken 的 API Key 和接入配置准备好。因为很多输入框场景本身就是用来发消息给模型的键盘体验和请求链路是连在一起的。TaoToken 的 API 地址是https://taotoken.net/api控制台里可以创建和管理 API Keys。如果你只是想在本地快速验证模型返回可以直接用模型对话页面如果是要长期跑编码类任务或者 Agent走 Coding Plan 更合适。接入文档里有各语言的示例照着改 base_url 和 key 就行。注意API Key 不要写在小程序前端代码里正式环境建议通过自己的后端转发前端只拿业务 token。这一步不是必须的但如果你后面要验证“输入框回车后请求模型”的完整链路提前把 key 和文档过一遍会省很多时间。3. cursor-spacing 与 focus 的可复制配置3.1 cursor-spacing 到底量的是哪段距离cursor-spacing的类型是 Number单位是 px。官方说明是“指定光标与键盘的距离”实际计算方式是取 input 距离页面底部的距离和 cursor-spacing 指定的距离两者中的最小值作为光标与键盘的距离。这句话有点绕拆开看假设你的 input 距离屏幕底部有 300pxcursor-spacing设成 20那么键盘弹起后光标和键盘之间保留 20px。如果 input 本身距离底部只有 10px那即使你写 20也只会保留 10px因为取的是最小值。所以cursor-spacing不是“强制推开多少”而是“最多保留多少”。input classmsg-input typetext placeholder说点什么 cursor-spacing20 adjust-position{{true}} focus{{inputFocus}} confirm-typesend confirm-hold{{true}} bindfocusonInputFocus bindbluronInputBlur bindconfirmonSend /上面这段里cursor-spacing20表示希望光标和键盘之间留 20px。adjust-position默认就是 true表示键盘弹起时页面自动上推。很多人只写cursor-spacing不写adjust-position在 iOS 上可能看起来正常但安卓某些机型上推幅度不够输入框还是贴边。3.2 focus 与 auto-focus 的区别auto-focus是 Boolean设为 true 时页面一打开就自动聚焦并拉起键盘。但这个属性官方已经标记即将废弃建议用focus代替。focus也是 Boolean但它更可控你可以用数据绑定在某个时机把它置为 true比如用户点击“回复”按钮后再聚焦。Page({ data: { inputFocus: false }, onReplyTap() { this.setData({ inputFocus: true }) }, onInputBlur() { this.setData({ inputFocus: false }) } })这样做的原因是如果一进页面就auto-focus键盘会立刻弹起可能遮挡页面顶部的标题或其他控件用户还没看清页面就被键盘占了一半。用focus配合用户主动操作体验更自然。3.3 adjust-position 与 confirm-hold 的配合adjust-position默认 true键盘弹起时页面自动上推。如果你把它设为 false页面不会自动上推这时候你就得自己用bindfocus拿到键盘高度手动设置margin-bottom或scroll-top。大多数场景保持 true 就行只有在你用了自定义滚动容器、或者页面结构特殊导致自动上推错位时才考虑关掉自己处理。confirm-hold控制点击键盘右下角按钮后键盘是否保持不收起。比如confirm-typesend时用户点“发送”如果confirm-hold为 false键盘会收起来设为 true键盘保持方便连续发送。聊天场景通常设 true。input cursor-spacing24 adjust-position{{true}} focus{{inputFocus}} confirm-typesend confirm-hold{{true}} bindconfirmonSend /3.4 不同机型与键盘弹起方式的差异iOS 和安卓的键盘弹起机制不一样。iOS 的键盘高度相对固定页面自动上推比较干脆安卓因为输入法五花八门有的键盘带候选词栏高度会变adjust-position上推后输入框位置可能偏上或偏下。另外全面屏机型底部有安全区cursor-spacing设太小会被 Home 指示条挡住。实测下来cursor-spacing在 16 到 32 之间比较舒服。太小会贴键盘太大在部分安卓机上会把输入框推得太高页面顶部内容被顶出屏幕。建议先设 20真机看效果再微调。4. 真机验证请求与成功结果配置写完必须真机验证模拟器只能看个大概。步骤可以这样走第一步在开发者工具里打开“真机调试”用手机扫码。第二步进入页面点击输入框观察键盘弹起后输入框是否完整可见。第三步在bindfocus里打印键盘高度和输入框位置。onInputFocus(e) { const { height, duration } e.detail console.log(键盘高度, height, 动画时长, duration) wx.createSelectorQuery() .select(.msg-input) .boundingClientRect(rect { console.log(输入框位置, rect) }) .exec() }bindfocus的事件对象里带height就是键盘高度。你可以拿这个值和输入框的bottom做对比如果rect.bottom大于windowHeight - height说明输入框被键盘盖住了需要调大cursor-spacing或者检查adjust-position是否生效。成功的结果是键盘弹起后输入框底部和键盘顶部之间保留你设定的间距输入框完整可见页面没有异常跳动。如果输入框还是被遮先看adjust-position是不是被设成了 false再看外层是不是用了position: fixed的容器导致自动上推失效。5. 本篇常见错排查问题一设了 cursor-spacing 但没效果。先确认adjust-position是 true。如果它是 false页面不上推cursor-spacing自然看不到效果。另外检查 input 是不是在scroll-view里scroll-view的滚动和键盘上推可能冲突需要手动处理滚动位置。问题二安卓上输入框被推得太高。这是adjust-position自动上推幅度和键盘实际高度不匹配导致的。可以尝试把cursor-spacing调小或者在bindfocus里拿到键盘高度后手动设置页面容器的padding-bottom同时把adjust-position设为 false。问题三focus 设了 true 但键盘不弹。focus需要是数据绑定且从 false 变成 true 才会触发。如果你在onLoad里直接设 true部分机型不弹。建议放在用户点击事件里setData。另外如果 input 被隐藏或display: nonefocus 也不会生效。问题四confirm-hold 不生效。确认confirm-type设了值比如send、search、next。如果confirm-type是默认的doneconfirm-hold的行为可能和预期不同。另外bindconfirm里如果有setData导致页面重新渲染键盘可能会收起。问题五iOS 上输入框和键盘之间有一条白边。这是安全区的问题。可以在 input 外层容器加padding-bottom: env(safe-area-inset-bottom)或者把cursor-spacing调大一点覆盖安全区高度。6. 把键盘距离调顺之后接入也可以顺手做掉键盘距离调好输入框不再被遮用户愿意打字了下一步往往就是把这些输入发给模型。如果你正在做对话类或编码辅助类小程序可以顺手把 TaoToken 的接入配好。API Keys 在控制台创建接入文档里有请求示例模型对话页面可以直接验证返回效果。长期跑编码任务的话Coding Plan 比按次调用更省心。回到键盘本身记住一个原则cursor-spacing管间距adjust-position管上推focus管时机confirm-hold管连续输入。四个属性各司其职真机上多试几组值找到你目标机型上最舒服的那个数。我自己的习惯是 iOS 设 20安卓设 28全面屏再加 8 的安全区余量你可以从这个基准开始调。