这里还有一点:
和
也很适合用于开发目的。通过对交互元素使用
/
,你可以更容易地为所有的交互元素创建一个CSS选择器:
button, a {
cursor: pointer; /* Using pointer is controversial, this is just an example */
}
4. 用
包裹字段和提交
-
+
- Login
确保将所有表单的字段及其提交
包装在
标签中。只有当字段位于< form >
标签内并且只有一个提交按钮时,使用Enter
提交表单才有效。(此外,使用屏幕阅读器的用户会喜欢这种实现提供的更好的导航。)
5. 避免使用placeholder
替代
-
+
+ E-mail:
+
+
创建placeholder
属性是为了显示输入的示例,而不是为了描述该输入。因此,我完全不建议将它用作
标记的替代品。此外,当用户输入数据时,占位符值将被隐藏,并且它们还经常存在对比度问题。
这对于简短的电子邮件+密码表单来说不是那么明显,但在较大的表单中占位符的问题就很明显了。
6. 用
标签包装复选框输入
- I agree with the privacy policy
+
+ I agree with the privacy policy
+
默认情况下,复选框输入的尺寸非常小,因此只能检测到很小的点击区域。这意味着用户需要更多的时间来精确地将光标放置在需要的位置。但是,如果复选框输入被包装在
标签中,那么单击其文本也会改变复选框的值。(另外,请注意,每个单独的复选框输入都需要自己的
标记。)
这样做的时候,最好添加一个清晰的悬停效果,让用户知道他们可以点击文本来触发输入:
label:hover {
background: oklch(0 0 0 / 10%);
}
7. 添加一个可见焦点状态
- *:focus {
- outline: none;
- }
+ button:focus-visible, a:focus-visible, input:focus-visible {
+ outline: 5px solid oklch(60% 0.15 252);
+ }
在我们的应用程序中,我们经常忘记或忽略键盘用户体验。但是当涉及到表单时,一般来说,每个用户都会使用键盘。我们需要考虑如何从键盘访问UI。
第一步是添加对比度:focus
状态以突出显示当前字段。用户将使用他们的周边视觉来确定焦点被移动的位置。Sara Soueidan写了一个很棒的指南,解释了如何使:focus
指示器清晰可见。
在为输入字段和按钮创建:focus
状态之后,也将其添加到
标记中。这是改善网站键盘可访问性的第一小步。
永远不要在你的应用中禁用:focus
状态。
另一个提示:如果您开发SPA并且想在单击菜单项后移除:focus
状态,请使用:focus-visible
。
8. 为屏幕阅读器标记无效字段
+ required aria-invalid="true" aria-errormessage="email-error">
Enter a valid email address
aria-invalid
和aria-errormessage
展示屏幕阅读器用户的验证错误。
另一个注意事项:通过使用required
属性警告屏幕阅读器用户关于必填字段也很不错。如果您不喜欢浏览器内置的required
验证,请确保在实现自己的验证时使用aria-required
属性。
9. 防止在用户输入中间进行验证
- input.addEventListener('keyup', () => {
- if (validate(input)) {
- markValid(input)
- } else {
- markInvalid(input)
- }
- })
+ input.addEventListener('input', () => {
+ if (validate(input)) {
+ markValid(input)
+ }
+ })
+ input.addEventListener('change', () => {
+ if (validate(input)) {
+ markValid(input)
+ } else {
+ markInvalid(input)
+ }
+ })
当用户在表单中输入数据时,我们不想让错误动画分散他们的注意力或让他们感到困惑,所以不要在用户还没有完成输入之前显示不是有效邮箱
的错误。
作为一种解决方案,在用户完成输入后(通过移动到另一个控件或提交表单),使用change
而不是keyup
进行验证。当然,我们仍然可以使用input
/keyup
,但只能隐藏输入过程中的错误。
下面是关于内联表单验证的一个很好的指南。
防止表单发送两次
form.addEventListener('submit', () => {
submit.disabled = true
// Fix for Firefox. It persists the dynamic disabled state without this hack.
submit.autocomplete = 'off'
// We are using setTimeout for page-reload submit.
// For AJAX, use await and try-finally to enable submit the button again.
setTimeout(() => {
button.disabled = false
}, 2000)
})
用户经常会不小心双击而不是单击。因此,为了防止显示一些服务器错误,最好在表单提交时禁用该按钮。
使用AJAX时,要考虑网络延迟和服务器/网络错误
form.addEventListener('submit', async () => {
- await fetch(…)
+ try {
+ showLoader()
+ await fetch(…)
+ } catch (e) {
+ showError(e)
+ } finally {
+ hideLoader()
+ }
})
对于每个AJAX请求,我们应该始终考虑两件事:
向用户显示加载状态 。在本地开发期间,您有0毫秒的延迟,但是真实用户在服务器响应之前将有几秒钟的延迟,因此用户应该在单击提交按钮后看到某种反馈。
处理网络和服务器错误 。你不会在本地开发中看到这种情况,但在生产环境中,每个用户都可能遇到WiFi连接失败
或服务器出现Error 500
错误;为它们做好准备,并向用户显示一些适当的文本。
注意:对于授权表单,最好通过页面重载提交表单,因为它会将用户的token保存到httpOnly-cookie
并更新web应用中的所有存储。
总结
设置autocomplete
输入字段
为输入字段选择正确的type
所有可点击的元素都应该使用
或
,而不是或
用
标签内包裹输入字段和提交
使用
描述
标签,避免placeholder
用
标签内包装复选框
为UI设置可视:focus
状态
为屏幕阅读器标记无效字段
阻止在输入中间进行验证
阻止表单发送两次
考虑网络延迟和服务器/网络错误