Skip to content

背景

登录表单通常需要同时满足两个目标:

  1. 保留浏览器和密码管理器的自动填充能力,降低登录成本。
  2. 去掉浏览器自动填充后给输入框加上的默认背景色、文字色,避免破坏设计稿。

不要为了去掉自动填充背景色而禁用自动填充。比如隐藏假字段、autocomplete="off"autocomplete="new-password"、聚焦前 readonly 等做法,确实可能绕开默认样式,但代价是浏览器无法稳定识别真实登录表单。

正确方向是:让浏览器识别真实字段,再用 CSS 覆盖 autofill 状态。

表单字段应该怎么写

登录表单应该使用标准的 autocomplete 语义:

vue
<a-form autocomplete="on">
  <a-input
    id="login_email"
    name="login_email"
    type="email"
    autocomplete="username"
  />

  <a-input-password
    id="login_password"
    name="login_password"
    autocomplete="current-password"
  />
</a-form>

如果手机号也可以作为账号登录,手机号输入框也应该传到真实的内部 input:

vue
<HPhoneInput
  input-id="login_phone"
  input-name="login_phone"
  autocomplete="username"
/>

注意:不要把登录密码写成 autocomplete="new-password"new-password 是注册、重置密码、新建密码场景使用的,不适合登录。

样式应该怎么覆盖

以 Ant Design Vue 登录页为例,a-input-password 内部真实输入框在 .ant-input-affix-wrapper input 里;如果当前页面样式是 scoped,要用 :deep(...) 打到组件内部。

推荐把覆盖范围限制在登录页容器,例如 .user-auth,避免影响全站表单:

less
:deep(.user-auth input:-webkit-autofill),
:deep(.user-auth input:-webkit-autofill:hover),
:deep(.user-auth input:-webkit-autofill:focus),
:deep(.user-auth .ant-input-affix-wrapper input:-webkit-autofill),
:deep(.user-auth .ant-input-affix-wrapper input:-webkit-autofill:hover),
:deep(.user-auth .ant-input-affix-wrapper input:-webkit-autofill:focus) {
  -webkit-text-fill-color: #ddd !important;
  color: #ddd !important;
  caret-color: #ddd;
  -webkit-box-shadow: 0 0 0 1000px transparent inset !important;
  box-shadow: 0 0 0 1000px transparent inset !important;
  background-color: transparent !important;
  background-image: none !important;
  -webkit-transition:
    color 5000s ease-out 5000s,
    background-color 5000s ease-out 5000s;
  -webkit-transition-delay: 5000s;
  transition:
    color 5000s ease-out 5000s,
    background-color 5000s ease-out 5000s;
  transition-delay: 5000s;
}

:deep(.user-auth input:-internal-autofill-previewed),
:deep(.user-auth input:-internal-autofill-selected) {
  -webkit-text-fill-color: #ddd !important;
  color: #ddd !important;
  caret-color: #ddd;
  -webkit-box-shadow: 0 0 0 1000px transparent inset !important;
  box-shadow: 0 0 0 1000px transparent inset !important;
  background-color: transparent !important;
  background-image: none !important;
  -webkit-transition:
    color 5000s ease-out 5000s,
    background-color 5000s ease-out 5000s;
  -webkit-transition-delay: 5000s;
  transition:
    color 5000s ease-out 5000s,
    background-color 5000s ease-out 5000s;
  transition-delay: 5000s;
}

:deep(.user-auth input:-moz-autofill),
:deep(.user-auth textarea:-moz-autofill),
:deep(.user-auth select:-moz-autofill) {
  box-shadow: 0 0 0 1000px transparent inset !important;
  background-color: transparent !important;
  caret-color: #ddd;
  color: #ddd !important;
}

为什么不要直接用实色盖住

有些资料会建议:

css
input:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px #101b36 inset !important;
}

这种写法在普通 input 上可能有效,但在 a-input-password 这类复合组件里容易出现问题:真实的 password input 高度通常比外层 wrapper 小,实色 inset 会只覆盖内部 input 的内容区域,从视觉上变成一条突兀的色带。

因此,如果输入框本身是透明、玻璃态、渐变背景或依赖父容器背景,优先使用透明覆盖和长 transition delay,而不是实色硬盖。

常见不生效原因

  1. 选择器打错组件库。

    Arco 的 .arco-form-item-status-error 打不到 Ant Design Vue 的 .ant-input.ant-input-affix-wrapper

  2. scoped 样式没有使用 :deep(...)

    组件库内部 input 不在当前组件 scope 里,普通 input:-webkit-autofill 可能命不中。

  3. 真实字段被干扰。

    如果真实输入框是 autocomplete="off"new-password,或者一开始是 readonly,浏览器可能不会进入正常登录 autofill 流程。

  4. 有旧样式冲突。

    例如旧规则里存在:

    css
    input:-webkit-autofill {
      box-shadow: 0 0 0 1000px #fff inset;
    }

    这类规则会把自动填充背景盖成白色,需要删除或提高正确规则的优先级。

  5. Chrome 内部状态没有覆盖。

    除了 :-webkit-autofill,Chrome 还可能出现 :-internal-autofill-previewed:-internal-autofill-selected。如果只覆盖前者,预览态或选中态可能仍有默认样式。

验收标准

  1. 浏览器能弹出已保存账号建议。
  2. 选择账号后,邮箱/手机号和密码能自动填入真实字段。
  3. 自动填入后,输入框不出现浏览器默认的黄色、蓝色、白色或异常色带。
  4. 密码框的眼睛图标、边框、placeholder、错误态样式不被破坏。
  5. 不影响注册、重置密码等需要 new-password 的场景。

推荐结论

保留浏览器自动填充的关键是标准字段语义:

  • 登录账号:autocomplete="username"
  • 登录密码:autocomplete="current-password"
  • 表单:autocomplete="on"

去掉默认样式的关键是命中真实 input 的 autofill 状态,并把覆盖范围限制在登录页:

  • :deep(.user-auth input:-webkit-autofill)
  • :deep(.user-auth input:-internal-autofill-selected)
  • :deep(.user-auth .ant-input-affix-wrapper input:-webkit-autofill)

不要用假字段或 readonly 绕开 autofill,也不要在透明输入框里直接用实色 inset shadow 硬盖。

本站总访问