Appearance
背景
登录表单通常需要同时满足两个目标:
- 保留浏览器和密码管理器的自动填充能力,降低登录成本。
- 去掉浏览器自动填充后给输入框加上的默认背景色、文字色,避免破坏设计稿。
不要为了去掉自动填充背景色而禁用自动填充。比如隐藏假字段、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,而不是实色硬盖。
常见不生效原因
选择器打错组件库。
Arco 的
.arco-form-item-status-error打不到 Ant Design Vue 的.ant-input、.ant-input-affix-wrapper。scoped样式没有使用:deep(...)。组件库内部 input 不在当前组件 scope 里,普通
input:-webkit-autofill可能命不中。真实字段被干扰。
如果真实输入框是
autocomplete="off"、new-password,或者一开始是readonly,浏览器可能不会进入正常登录 autofill 流程。有旧样式冲突。
例如旧规则里存在:
cssinput:-webkit-autofill { box-shadow: 0 0 0 1000px #fff inset; }这类规则会把自动填充背景盖成白色,需要删除或提高正确规则的优先级。
Chrome 内部状态没有覆盖。
除了
:-webkit-autofill,Chrome 还可能出现:-internal-autofill-previewed和:-internal-autofill-selected。如果只覆盖前者,预览态或选中态可能仍有默认样式。
验收标准
- 浏览器能弹出已保存账号建议。
- 选择账号后,邮箱/手机号和密码能自动填入真实字段。
- 自动填入后,输入框不出现浏览器默认的黄色、蓝色、白色或异常色带。
- 密码框的眼睛图标、边框、placeholder、错误态样式不被破坏。
- 不影响注册、重置密码等需要
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 硬盖。