阅读提要

表单是用户和系统之间最容易出摩擦的地方。这份清单覆盖标签、错误提示、提交态、输入类型和键盘操作五块,每一条都对应一个真实的体验损失。

开始阅读

字号

为什么单独讲表单

其他页面做得再好,用户也可能只碰一个表单:注册、登录、下单、留言。

表单出问题的方式又特别隐蔽——不报错,不崩溃,只是让用户多花三十秒、多试两次、最后放弃。这类损失不会出现在监控里,只会出现在转化率上。

下面五块,按影响从大到小排。

表单关键点

一、标签不能靠占位符

最常见的错误:

<input placeholder="请输入邮箱">

占位符有两个致命问题:一输入就消失(用户忘了这栏填什么),对比度通常很低(浅灰色,视力差的人看不清)。

正确做法是显式的 <label>:

<label for="email">邮箱</label>
<input id="email" type="email" autocomplete="email">

如果设计上确实不想要可见标签,至少用 aria-label 或视觉隐藏的 label,保证屏幕阅读器能读到。

for 和 id 的关联还有一个好处:点标签能聚焦输入框,触屏上好用得多。

二、错误提示要落在字段上

提交后弹一个 Toast「请检查输入」,是最差的做法——用户得自己找哪一项错了。

字段级提示:

<input
  id="email"
  aria-invalid="true"
  aria-describedby="email-error"
>
<p id="email-error" role="alert">邮箱格式不正确,例如 name@example.com</p>

三个要点:

  • 位置:紧贴字段下方,不要放到表单顶部;
  • 文案:说清「哪里错了」和「怎么改」,不要只说「格式错误」;
  • 可访问性:aria-invalid + aria-describedby,让读屏软件能关联错误与字段。

还有一个细节:校验时机。输入过程中实时校验会让人抓狂(刚打第一个字符就报错)。常见做法是「失焦时校验,提交时全量校验,改错后立即清除错误」。

三、提交态必须可见

点击提交后,如果按钮没反应,用户会再点一次、两次、三次——于是产生三条重复数据。

async function submit() {
  if (submitting.value) return
  submitting.value = true
  try {
    await api.save(payload)
  } finally {
    submitting.value = false
  }
}

按钮上要体现状态:disabled + 文案变成「提交中…」+ 一个旋转图标。三件事一起做,用户才知道「系统收到了」。

注意:disabled 会让按钮失去焦点,键盘用户会丢失位置。更好的做法是 aria-disabled="true" + 阻止重复提交,保留焦点。

四、输入类型决定手机键盘

这一条在移动端影响巨大:

<input type="email">        <!-- 键盘带 @ 和 . -->
<input type="tel">          <!-- 数字键盘 -->
<input type="number" inputmode="numeric">  <!-- 纯数字 -->
<input type="url">          <!-- 带 / 和 .com -->

验证码用 inputmode="numeric" + autocomplete="one-time-code",iOS 和 Android 都能自动填充短信验证码。

type="number" 有两个坑:允许输入 e 和 -;滚轮会误改数值。金额、数量这类字段,用 inputmode="numeric" + pattern="[0-9]*" 更稳。

五、键盘能走完全程

用户填一个表单,手不应该离开键盘。

  • Tab 顺序要和视觉顺序一致(别用 tabindex 正数打乱);
  • Enter 在单行输入里应该提交(多行文本框除外);
  • 焦点要有明显的可见样式(不要 outline: none 了事);
  • 提交失败后,焦点移到第一个出错的字段。

最后一条最容易被忽略:长表单里,用户在底部点提交,错误在第一项,屏幕上什么都看不到。

还有几条零散的

自动填充属性要写全。 autocomplete="email"、autocomplete="current-password"、autocomplete="new-password"。写对了,密码管理器才愿意帮忙。注册和登录的密码框要用不同的值,否则浏览器会拿旧密码填新密码框。

必填项要有视觉标识,但不要只用星号。 星号对读屏软件不友好,用 required 属性 + 文案说明「以下均为必填」。

长表单要能分段。 一屏塞 20 个字段,用户会产生放弃的念头。分成两三步,每步 5-8 项,完成率明显更高。

不要在输入时清空已填内容。 校验失败后重新渲染表单,把用户填的东西弄丢,是最让人恼火的 bug。

一个自查清单

上线前逐条过:

  1. 每个输入都有可见标签,且 for 关联正确;
  2. 错误信息在字段旁,说明怎么改;
  3. 提交按钮有加载态,且防重复提交;
  4. 移动端键盘类型正确;
  5. Tab 能走完全程,焦点样式可见;
  6. 自动填充属性写全;
  7. 校验失败不丢用户输入。

七条做到,表单的体验就从「能用」变成「不难用」。这个差别在转化率上通常是两位数。

你认为这篇文章怎么样?

还没有表情反馈

分享文章