autocomplete:告诉浏览器这个字段是什么
autocomplete 不是「开 / 关」那么简单。除了 on / off,它的值还可以是一串有序 token:用一个字段名 token(如 given-name / postal-code /
cc-number)告诉浏览器与密码管理器「这个框该填什么语义的数据」,前面再依次缀上可选的 section-* 分组、shipping / billing 用途、home / work 等联系方式限定。本页用一个 token
解析器把这套语法拆开,再把它和另外两个正交的维度——type(数据类型)与 inputmode(软键盘)——摆在一起对照。真实的自动填充依赖浏览器登录态与用户已存数据,无法在 demo 里稳定触发,故本页以结构化讲解 + 语法解析为主。
1 · token 语法:顺序固定,字段名必需
在下面输入一个 autocomplete 值(或点预置例子),解析器会按规范顺序把它拆成各分量并标注角色。完整语法依次为(除字段名外都可选,但顺序固定):section-* → shipping | billing → 联系方式(home / work /
mobile / fax / pager)→ 字段名 token(必需) → 可选 webauthn。
角色约束。section-* 是任意自定义前缀,用来把多组同类字段(如「家庭地址」「公司地址」)区分开,必须排在最前。shipping / billing 只用于地址类字段;home / work / mobile / fax /
pager 这组联系方式限定只用于 tel / email / impp 等。它们都是可选的修饰,真正必需的是末尾那个字段名 token——没有它,整串就只能退回 on / off 的理解。
2 · 常用字段名 token
| 场景 | 字段名 token |
|---|---|
| 姓名 | name · given-name · family-name · nickname |
| 账户 | username · new-password · current-password · one-time-code |
| 地址 | organization · street-address · address-line1 / address-line2 · address-level2(市) · postal-code · country / country-name |
| 联系 | tel · email |
| 银行卡 | cc-name · cc-number · cc-exp · cc-csc |
| 其他 | bday · sex · url · photo |
3 · 三个正交维度:type / autocomplete / inputmode
规范(4.10.1.7)反复强调:一个字段上有三件互不干扰的事——它是什么数据类型、它语义上该填什么、用户打字时弹什么软键盘。三者可独立设置,不要混为一谈。最典型的反例就是短信验证码框:它是普通文本(type="text"),却要数字软键盘(inputmode="numeric")、又要被识别为一次性验证码(autocomplete="one-time-code")。
| 维度 | HTML API | 说明 |
|---|---|---|
| field type | <input type> / <select> |
决定数据类型与原生 UI / 校验:type="email" 给邮箱格式校验,type="date" 给日历选择器,type="number" 给步进器。详见 type 与状态机。 |
| autofill field name | autocomplete |
决定语义:让浏览器 / 密码管理器知道这框该填什么(姓、邮编、卡号、新密码……),从而自动填充或建议保存。不影响 UI,也不影响键盘。 |
| input modality | inputmode |
决定软键盘布局:numeric 数字键、tel 拨号盘、email 带 @。纯触屏键盘提示,不改数据类型也不改语义。详见 inputmode。 |
| 字段 | type(数据类型 / UI) |
autocomplete(语义) |
inputmode(软键盘) |
|---|---|---|---|
| 姓名 | text |
name |
(默认) |
| 邮箱 | email |
email |
email |
| 验证码 | text |
one-time-code |
numeric |
| 卡号 | text |
cc-number |
numeric |
| 密码 | password |
new-password |
(默认) |
4 · 一份能被密码管理器识别的注册表单
把每个框标对 token,浏览器与密码管理器才能把它们当成一组账户凭证去填充 / 保存。注意 given-name / family-name 各占一框、验证码框三个维度各司其职、注册密码用 new-password(而非 current-password)。下面只展示 markup,真实自动填充需在浏览器登录态、且用户已存有对应数据时才会发生。
<form action="/register" method="post" autocomplete="on">
<input name="first" type="text"
autocomplete="given-name" />
<input name="last" type="text"
autocomplete="family-name" />
<input name="email" type="email"
inputmode="email"
autocomplete="email" />
<!-- 短信验证码:三维各管一摊 -->
<input name="otp" type="text"
inputmode="numeric"
autocomplete="one-time-code" />
<!-- 注册密码:让密码管理器生成强密码 -->
<input name="pw" type="password"
autocomplete="new-password" />
<!-- 收货地址:section + 用途 + 字段名 -->
<input name="zip" type="text"
inputmode="numeric"
autocomplete="section-ship shipping postal-code" />
</form>
autocomplete="off" 常被浏览器忽略。尤其在密码、地址等敏感字段上,Chrome / Safari 出于「帮用户记住凭证」的产品判断会无视 off 照样提示填充。要真正改变填充行为,正确做法是给出准确的字段名 token
让浏览器各归其位,而不是试图用 off 全局关掉。
new-password vs current-password。注册 / 改密页的密码框用 new-password——它示意密码管理器生成一个强密码而不是回填旧的;登录页的密码框才用 current-password 触发回填已存凭证。把两者写反,会出现「注册时被填入旧密码」或「登录时不弹建议」这类体验问题。
one-time-code 配合短信 OTP。当验证码框标 autocomplete="one-time-code",iOS Safari / Android Chrome 能从短信里解析出验证码并自动填入(iOS 直接给输入建议条,Android 配合 WebOTP API)。username webauthn 则把字段并入 passkey
流程。要点是:这些都靠语义 token 驱动,与 type 状态 决定的数据类型、inputmode 决定的软键盘相互独立。