Use cross-platform browser features to build sign-in forms that are secure, accessible and easy to use.
如果用户需要登录到您的网站,那么良好的登录表单设计至关重要。对于网络连接不良、使用移动设备、时间匆忙或压力大的用户来说尤其如此。设计糟糕的登录表单跳出率很高。每次跳出都可能意味着失去一位不满意的用户,而不仅仅是错失一次登录机会。
这是一个简单登录表单的示例,演示了所有最佳实践
清单
- 使用有意义的 HTML 元素:
<form>
、<input>
、<label>
和<button>
。 - 使用
<label>
标记每个输入. - 使用元素属性来访问内置浏览器功能:
type
、name
、autocomplete
、required
。 - 为输入
name
和id
属性赋予稳定的值,这些值在页面加载或网站部署之间不会更改。 - 将登录放在其自己的 <form> 元素中。
- 确保表单成功提交.
- 在注册表单的密码输入中以及重置密码表单的新密码中使用
autocomplete="new-password"
和id="new-password"
。 - 在登录密码输入中使用
autocomplete="current-password"
和id="current-password"
。 - 提供显示密码功能。
- 对密码输入使用
aria-label
和aria-describedby
。 - 不要重复输入.
- 设计表单时,确保移动设备键盘不会遮挡输入或按钮。
- 确保表单在移动设备上可用:使用清晰易读的文本,并确保输入和按钮足够大,可以用作触摸目标。
- 在您的注册和登录页面上保持品牌形象和风格。
- 在实际环境和实验室中进行测试:在您的注册和登录流程中构建页面分析、互动分析和以用户为中心的性能衡量。
- 跨浏览器和设备进行测试:表单行为在不同平台之间差异很大。
使用有意义的 HTML
使用为工作而构建的元素:<form>
、<label>
和 <button>
。这些元素启用内置浏览器功能,提高可访问性,并为您的标记添加含义。
使用 <form>
您可能很想将输入包装在 <div>
中,并纯粹使用 JavaScript 处理输入数据提交。通常最好使用普通的旧式 <form>
元素。这使您的网站可供屏幕阅读器和其他辅助设备访问,启用了一系列内置浏览器功能,使构建适用于旧版浏览器的基本功能性登录更简单,并且即使 JavaScript 失败也可以正常工作。
使用 <label>
要标记输入,请使用 <label>
!
<label for="email">Email</label>
<input id="email" …>
两个原因
- 点击或单击标签会将焦点移动到其输入。通过将标签的
for
属性与输入的name
或id
关联,将标签与输入关联起来。 - 当标签或标签的输入获得焦点时,屏幕阅读器会朗读标签文本。
不要使用占位符作为输入标签。人们很容易忘记输入的用途,尤其是在他们开始输入文本后分心时(“我输入的是电子邮件地址、电话号码还是帐户 ID?”)。占位符还有许多其他潜在问题:如果您仍未信服,请参阅 不要使用占位符属性 和 表单字段中的占位符有害。
最好将标签放在输入上方。根据 Google AI 研究,这可以在移动设备和桌面设备上实现一致的设计,并使用户能够更快地扫描。您可以获得全宽标签和输入,并且无需调整标签和输入宽度以适应标签文本。

在移动设备上打开 label-position Glitch,亲身体验一下。
使用 <button>
按钮请使用 <button>
!按钮元素提供可访问的行为和内置的表单提交功能,并且可以轻松设置样式。使用 <div>
或其他元素来冒充按钮毫无意义。
确保提交按钮说明其用途。例如,使用创建帐户或登录,而不是提交或开始。
确保表单成功提交
帮助密码管理器了解表单已提交。有两种方法可以做到这一点
- 导航到不同的页面。
- 使用
History.pushState()
或History.replaceState()
模拟导航,并删除密码表单。
对于 XMLHttpRequest
或 fetch
请求,请确保在响应中报告登录成功,并通过从 DOM 中删除表单以及向用户指示成功来处理登录成功。
考虑在用户点击或单击登录按钮后禁用该按钮。许多用户多次单击按钮,即使在快速响应的网站上也是如此。这会减慢互动速度并增加服务器负载。
相反,不要在等待用户输入时禁用表单提交。例如,如果用户尚未输入其客户 PIN 码,请不要禁用登录按钮。用户可能会遗漏表单中的某些内容,然后反复尝试点击(已禁用的)登录按钮,并认为它无法正常工作。至少,如果您必须禁用表单提交,请在用户单击已禁用的按钮时向他们解释缺少的内容。
不要重复输入
某些网站强制用户输入两次电子邮件或密码。这可能会减少少数用户的错误,但会给所有用户带来额外的工作,并增加放弃率。当浏览器自动填充电子邮件地址或建议强密码时,要求输入两次也没有意义。最好是让用户确认他们的电子邮件地址(无论如何您都需要这样做),并让他们在必要时轻松重置密码。
充分利用元素属性
这就是奇迹真正发生的地方!浏览器具有多个有用的内置功能,这些功能使用输入元素属性。
保持密码私密性,但允许用户在需要时查看密码
密码输入应具有 type="password"
以隐藏密码文本,并帮助浏览器了解输入是用于密码的。(请注意,浏览器使用多种技术来理解输入角色,并决定是否提供保存密码。)
您应该添加一个显示密码切换,使用户能够检查他们输入的文本,并且不要忘记添加忘记密码链接。请参阅启用密码显示。

为移动用户提供正确的键盘
使用 <input type="email">
为移动用户提供合适的键盘,并启用浏览器内置的基本电子邮件地址验证... 无需 JavaScript!
如果您需要使用电话号码而不是电子邮件地址,<input type="tel">
会在移动设备上启用电话键盘。您也可以在必要时使用 inputmode
属性:inputmode="numeric"
非常适合 PIN 码。您一直想了解的关于 inputmode 的一切 提供了更多详细信息。
防止移动设备键盘遮挡登录按钮
不幸的是,如果您不小心,移动设备键盘可能会覆盖您的表单,或者更糟糕的是,部分遮挡登录按钮。用户可能会在意识到发生了什么之前放弃。

在可能的情况下,避免这种情况的方法是在登录页面顶部仅显示电子邮件/电话和密码输入以及登录按钮。将其他内容放在下面。

在一系列设备上进行测试
您需要在目标受众的一系列设备上进行测试,并进行相应的调整。BrowserStack 允许为开源项目在一系列真实设备和浏览器上进行免费测试。

考虑使用两个页面
一些网站(包括亚马逊和 eBay)通过在两个页面上询问电子邮件/电话和密码来避免此问题。这种方法还简化了体验:用户一次只处理一件事情。

理想情况下,这应使用单个 <form> 来实现。使用 JavaScript 最初仅显示电子邮件输入,然后隐藏它并显示密码输入。如果您必须强制用户在输入电子邮件和密码之间导航到新页面,则第二个页面上的表单应具有带有电子邮件值的隐藏输入元素,以帮助密码管理器存储正确的值。Chromium 理解的密码表单样式提供了一个代码示例。
帮助用户避免重新输入数据
您可以帮助浏览器正确存储数据并自动填充输入,这样用户就不必记住输入电子邮件和密码值。这在移动设备上尤其重要,对于电子邮件输入至关重要,电子邮件输入的放弃率很高。
这包括两个部分
autocomplete
、name
、id
和type
属性帮助浏览器了解输入的角色,以便存储稍后可用于自动填充的数据。为了允许存储数据以进行自动填充,现代浏览器还要求输入具有稳定的name
或id
值(而不是在每次页面加载或网站部署时随机生成),并且位于带有submit
按钮的 <form> 中。autocomplete
属性帮助浏览器使用存储的数据正确地自动填充输入。
对于电子邮件输入,请使用 autocomplete="username"
,因为 username
被现代浏览器中的密码管理器识别,即使您应该使用 type="email"
,并且您可能希望使用 id="email"
和 name="email"
。
对于密码输入,请使用适当的 autocomplete
和 id
值,以帮助浏览器区分新密码和当前密码。
对于新密码,请使用 autocomplete="new-password"
和 id="new-password"
- 对于注册表单中的密码输入或更改密码表单中的新密码,请使用
autocomplete="new-password"
和id="new-password"
。
对于现有密码,请使用 autocomplete="current-password"
和 id="current-password"
- 对于登录表单中的密码输入或更改密码表单中用户旧密码的输入,请使用
autocomplete="current-password"
和id="current-password"
。这告诉浏览器您希望它使用它为该站点存储的当前密码。
对于注册表单
<input type="password" autocomplete="new-password" id="new-password" …>
对于登录
<input type="password" autocomplete="current-password" id="current-password" …>
支持密码管理器
不同的浏览器处理电子邮件自动填充和密码建议的方式略有不同,但效果大致相同。例如,在桌面设备上的 Safari 11 及更高版本中,会显示密码管理器,然后如果可用,则使用生物特征识别身份验证(指纹或面部识别)。

桌面设备上的 Chrome 会显示电子邮件建议,显示密码管理器,并自动填充密码。

浏览器密码和自动填充系统并非简单。用于猜测、存储和显示值的算法未标准化,并且因平台而异。例如,正如 Hidde de Vries 指出的那样:“Firefox 的密码管理器使用 配方系统来补充其启发式方法。”
自动填充:Web 开发者应该知道但不知道的内容 提供了更多关于使用 name
和 autocomplete
的信息。HTML 规范列出了所有 59 个可能的值。
启用浏览器以建议强密码
现代浏览器使用启发式方法来决定何时显示密码管理器 UI 并建议强密码。
以下是 Safari 在桌面设备上的做法。

(自 12.0 版本以来,Safari 中已提供强而独特的密码建议。)
内置浏览器密码生成器意味着用户和开发者无需弄清楚什么是“强密码”。由于浏览器可以安全地存储密码并在必要时自动填充密码,因此用户无需记住或输入密码。鼓励用户利用内置浏览器密码生成器也意味着他们更有可能在您的网站上使用唯一的强密码,并且不太可能重用可能在其他地方泄露的密码。
帮助用户避免意外遗漏输入
将 required
属性添加到电子邮件和密码字段。现代浏览器会自动提示并为缺少的数据设置焦点。无需 JavaScript!

为手指和拇指设计
几乎所有与输入元素和按钮相关的默认浏览器尺寸都太小,尤其是在移动设备上。这似乎显而易见,但这是许多网站登录表单的常见问题。
确保输入和按钮足够大
输入和按钮的默认大小和内边距在桌面设备上太小,在移动设备上甚至更糟。

根据 Android 辅助功能指南,触摸屏对象的建议目标尺寸为 7-10 毫米。Apple 界面指南建议 48x48 像素,W3C 建议至少 44x44 CSS 像素。在此基础上,为移动设备的输入元素和按钮添加(至少)约 15 像素的内边距,为桌面设备添加约 10 像素的内边距。使用真实的移动设备和真实的手指或拇指进行尝试。您应该能够舒适地点击每个输入和按钮。
点击目标尺寸不合适 Lighthouse 审核可以帮助您自动化检测尺寸过小的输入元素的过程。
为拇指设计
搜索 touch target,您会看到很多食指的图片。但是,在现实世界中,许多人使用拇指与手机互动。拇指比食指大,并且控制不太精确。因此,更有理由使用尺寸足够大的触摸目标。
使文本足够大
与大小和内边距一样,输入元素和按钮的默认浏览器字体大小太小,尤其是在移动设备上。

不同平台上的浏览器对字体大小的呈现方式不同,因此很难指定一个在所有地方都效果良好的特定字体大小。对热门网站的快速调查显示,桌面端字体大小为 13–16 像素:在移动设备上,与该物理尺寸匹配是一个很好的文本最小尺寸。
这意味着您需要在移动设备上使用更大的像素尺寸:在桌面版 Chrome 上,16px
非常清晰易读,但即使视力良好,在 Android 版 Chrome 上阅读 16px
的文本也很困难。您可以使用 媒体查询 为不同的视口尺寸设置不同的字体像素大小。20px
在移动设备上大致合适——但您应该与视力不佳的朋友或同事一起测试一下。
“文档未使用清晰易读的字体大小” Lighthouse 审核可以帮助您自动化检测过小文本的过程。
在输入框之间提供足够的空间
添加足够的边距,使输入框能够很好地作为触摸目标。换句话说,目标是大约一个手指宽度的边距。
确保您的输入框清晰可见
输入框的默认边框样式使其难以看清。在某些平台(如 Android 版 Chrome)上,它们几乎是不可见的。
除了内边距之外,还要添加边框:在白色背景上,一个好的通用规则是使用 #ccc
或更深的颜色。

使用内置浏览器功能来警告无效的输入值
浏览器具有内置功能,可以对带有 type
属性的输入框进行基本表单验证。当您提交包含无效值的表单时,浏览器会发出警告,并将焦点设置在有问题的输入框上。

您可以使用 :invalid
CSS 选择器来突出显示无效数据。使用 :not(:placeholder-shown)
以避免选择没有内容的输入框。
input[type=email]:not(:placeholder-shown):invalid {
color: red;
outline-color: red;
}
尝试使用不同的方式来突出显示具有无效值的输入框。
在必要时使用 JavaScript
切换密码显示
您应该添加一个显示密码切换开关,以便用户检查他们输入的文本。当用户看不到他们输入的文本时,可用性会降低。目前,还没有内置的方法来实现这一点,尽管 有计划实施。您需要改用 JavaScript。

以下代码使用文本按钮来添加显示密码功能。
HTML
<section>
<label for="password">Password</label>
<button id="toggle-password" type="button" aria-label="Show password as plain text. Warning: this will display your password on the screen.">Show password</button>
<input id="password" name="password" type="password" autocomplete="current-password" required>
</section>
这是使按钮看起来像纯文本的 CSS
button#toggle-password {
background: none;
border: none;
cursor: pointer;
/* Media query isn't shown here. */
font-size: var(--mobile-font-size);
font-weight: 300;
padding: 0;
/* Display at the top right of the container */
position: absolute;
top: 0;
right: 0;
}
以及用于显示密码的 JavaScript
const passwordInput = document.getElementById('password');
const togglePasswordButton = document.getElementById('toggle-password');
togglePasswordButton.addEventListener('click', togglePassword);
function togglePassword() {
if (passwordInput.type === 'password') {
passwordInput.type = 'text';
togglePasswordButton.textContent = 'Hide password';
togglePasswordButton.setAttribute('aria-label',
'Hide password.');
} else {
passwordInput.type = 'password';
togglePasswordButton.textContent = 'Show password';
togglePasswordButton.setAttribute('aria-label',
'Show password as plain text. ' +
'Warning: this will display your password on the screen.');
}
}
这是最终结果

使密码输入框可访问
使用 aria-describedby
来概述密码规则,方法是为其提供描述约束的元素的 ID。屏幕阅读器会提供标签文本、输入类型(密码),然后是描述。
<input type="password" aria-describedby="password-constraints" …>
<div id="password-constraints">Eight or more characters with a mix of letters, numbers and symbols.</div>
当您添加显示密码功能时,请务必包含 aria-label
以警告密码将被显示。否则,用户可能会在不经意间泄露密码。
<button id="toggle-password"
aria-label="Show password as plain text.
Warning: this will display your password on the screen.">
Show password
</button>
您可以在以下 Glitch 中看到 ARIA 功能的实际应用
“创建可访问的表单” 提供了更多帮助使表单可访问的技巧。
实时验证和提交前验证
HTML 表单元素和属性具有用于基本验证的内置功能,但您还应该在用户输入数据时以及他们尝试提交表单时使用 JavaScript 进行更强大的验证。
登录表单代码实验室的步骤 5 使用 Constraint Validation API(广泛支持)来添加自定义验证,使用内置浏览器 UI 来设置焦点和显示提示。
了解更多:“使用 JavaScript 进行更复杂的实时验证”。
分析和 RUM
“无法衡量,就无法改进” 这句话对于注册和登录表单尤其适用。您需要设定目标、衡量成功、改进您的网站 — 并重复此过程。
“低成本可用性测试” 可能有助于尝试更改,但您需要真实世界的数据来真正了解您的用户如何体验您的注册和登录表单。
- 页面分析:注册和登录页面浏览量、跳出率和退出。
- 交互分析:目标渠道(用户在哪里放弃您的注册或登录流程?)和 事件(用户在与您的表单交互时采取哪些操作?)。
- 网站性能:以用户为中心的指标(您的注册和登录表单是否因某种原因而缓慢?如果是,原因是什么?)。
您可能还需要考虑实施 A/B 测试,以便尝试不同的注册和登录方法,并进行分阶段发布,以便在向所有用户发布更改之前,先在一部分用户身上验证更改。
通用指南
良好设计的 UI 和 UX 可以减少登录表单的放弃率
- 不要让用户到处寻找登录入口!将登录表单的链接放在页面顶部,使用易于理解的措辞,例如登录、创建帐户或注册。
- 保持专注!注册表单不是用优惠和其他网站功能分散人们注意力的地方。
- 尽量减少注册的复杂性。仅当用户看到提供其他用户数据(如地址或信用卡详细信息)的明确好处时,才收集这些数据。
- 在用户开始填写您的注册表单之前,请明确说明价值主张是什么。他们从登录中获得什么好处?为用户提供完成注册的具体激励。
- 如果可能,允许用户使用手机号码而不是电子邮件地址来识别自己,因为有些用户可能不使用电子邮件。
- 让用户可以轻松重置密码,并使忘记密码?链接显而易见。
- 链接到您的服务条款和隐私政策文档:从一开始就向用户明确您如何保护他们的数据。
- 在您的注册和登录页面上包含您公司或组织的徽标和名称,并确保语言、字体和样式与您网站的其余部分相匹配。有些表单感觉不像是与其他内容属于同一个网站,尤其是当它们的 URL 明显不同时。
持续学习
- 创建出色的表单
- 移动表单设计的最佳实践
- 功能更强大的表单控件
- 创建可访问的表单
- 使用 Credential Management API 简化登录流程
- 使用 WebOTP API 在 Web 上验证电话号码
照片由 Meghan Schiereck 拍摄于 Unsplash。