结论:inputmode 决定移动端弹哪种软键盘,autocomplete 决定浏览器能不能帮你自动填;两者职责完全不同,都不能做校验,正确的移动端表单是两个都写、再配 pattern 兜底。
inputmode 和 autocomplete 有什么区别?
一句话分工:inputmode 是给软键盘看的提示,autocomplete 是给自动填充引擎看的语义标签。
inputmode:只影响有虚拟键盘的环境(iOS Safari 12.2+、Chrome for Android 66+ 起支持),桌面浏览器基本无感。它不会限制用户输入什么,用户照样能粘贴一段中文进去。
autocomplete:告诉浏览器"这是手机号 / 这是短信验证码 / 这是新密码",浏览器据此从已保存的地址、支付信息、密码库里取值填入。它同样不做校验。
结论:只写 inputmode,键盘对了但用户还得手打;只写 autocomplete,浏览器能填但键盘可能还是全键盘。两个都写,再把校验交给 pattern 和服务端。
inputmode 有哪些取值,分别弹什么键盘?
inputmode 是全局属性,标准取值 8 个:none、text、tel、url、email、numeric、decimal、search。
常用的 4 个:numeric 弹纯数字键盘(无小数点);decimal 弹带小数分隔符的数字键盘;tel 弹电话键盘(含 * # +);email 弹带 @ 和 . 的键盘;search 会把回车键文案变成"搜索"。inputmode="none" 表示不弹键盘,用于自定义键盘或日期选择器的场景。
配合 enterkeyhint(取值 next、go、search、send、done、previous、enter)改回车键文案,多字段表单里体验提升很明显。
手机号、验证码、金额、信用卡该怎么写?
直接给可用代码,全是已验证的写法:
<!-- 手机号:type=tel 本身不校验,还能弹电话键盘 -->
<input type="tel" inputmode="tel" autocomplete="tel" enterkeyhint="next">
<!-- 短信验证码:iOS 12+ 可从短信直接填入 -->
<input type="text" inputmode="numeric" autocomplete="one-time-code"
maxlength="6" pattern="[0-9]{6}">
<!-- 金额 -->
<input type="text" inputmode="decimal" pattern="[0-9]*[.,]?[0-9]{0,2}">
<!-- 信用卡 -->
<input type="text" inputmode="numeric" autocomplete="cc-number" pattern="[0-9 ]{12,23}">
<input type="text" inputmode="numeric" autocomplete="cc-exp" placeholder="MM/YY">
<input type="text" inputmode="numeric" autocomplete="cc-csc" maxlength="4">
结论:验证码字段用 type="text" + inputmode="numeric" + autocomplete="one-time-code",这是目前 iOS 和 Android Chrome 都能识别短信验证码的写法。
地址类字段建议用 section-* 和 shipping/billing 前缀区分同页多份地址,例如 autocomplete="shipping street-address" 和 autocomplete="billing postal-code",否则浏览器会把两份地址填串。
为什么不要用 type="number" 做卡号、验证码、金额?
结论:type="number" 在移动端是坑,卡号、验证码、邮编、金额一律用 type="text" + inputmode。
原因有三个:一是它允许输入 e、+、-、.,用户输入 1e3 这类非法值时,input.value 直接返回空字符串,校验和提交一起翻车;二是浏览器对前导零和地区化小数点的处理不一致;三是桌面端有滚轮误改值的经典问题。用 type="text" 加 inputmode + pattern,键盘一样对,行为完全可控。
autocomplete 有哪些值最值得用?
除了上文的 one-time-code,高频的还有:密码框的 current-password(登录)和 new-password(注册/改密,会触发浏览器的强密码建议)、cc-number/cc-exp/cc-csc、email、tel、postal-code、street-address、address-line1、country。
结论:登录页的密码框不要写 autocomplete="off",Chrome 和 Safari 会直接忽略它;想阻止自动填充已有密码,正确做法是注册/改密场景写 autocomplete="new-password"。
React 项目里记得用驼峰:inputMode="numeric"、autoComplete="one-time-code"、enterKeyHint="next"。
收束一下:inputmode 管键盘形态、autocomplete 管自动填充、pattern 管格式校验,三者各司其职,配上 enterkeyhint 改善回车键文案,一个移动端表单该有的输入体验就齐了。