← HTML 表单:从控件到提交与校验 / autocomplete:告诉浏览器这个字段是什么 待审核 20 / 24
autocomplete · autofill

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 决定的软键盘相互独立。