Skip to content

表单字段 Field

表单字段 = 标签 + 控件 + 提示 / 错误。所有表单控件(输入框、下拉选择、日期、验证码、上传……)都按这个结构组织。

结构

examples/field/anatomy.html
html
<div class="flex flex-col gap-2">
  <label for="email" class="text-sm font-medium text-foreground">
    联系邮箱<span class="text-destructive" aria-hidden="true"> *</span>
  </label>
  <input id="email" required aria-describedby="email-hint" class="…" />
  <p id="email-hint" class="text-xs leading-relaxed text-muted-foreground">审核结果将发送至此邮箱。</p>
</div>
部分类名说明
字段容器flex flex-col gap-2标签、控件、提示之间 8px
标签text-sm font-medium text-foreground必须用 <label for> 关联控件
必填标记text-destructive + aria-hidden="true"控件本身加 required
提示text-xs leading-relaxed text-muted-foregroundaria-describedby 关联
错误flex items-start gap-1.5 text-xs leading-relaxed text-destructive前置 circle-alert 图标

错误状态

错误状态由控件上的 aria-invalid="true" 驱动:控件描边变红,焦点环变为红色。

html
<input aria-invalid="true" aria-describedby="name-error" class="… aria-invalid:border-destructive aria-invalid:focus:ring-destructive/20" />
<p id="name-error" class="flex items-start gap-1.5 text-xs text-destructive">…</p>
  • 错误文案出现时替换提示文案,而不是叠加在下方
  • 校验时机:失焦或提交时校验;用户修改后立即清除错误

表单布局

examples/field/form-layout.html
  • 字段之间 24px(gap-6),双列在 sm 以上启用:grid gap-6 sm:grid-cols-2
  • 关系紧密的字段(姓 / 名、区号 / 号码)放在同一行
  • 一组字段用 <fieldset> + <legend> 包裹
  • 表单底部按钮:移动端纵向通栏、主要操作在上;桌面端右对齐、主要操作在右

使用建议

推荐

  • 标签简洁、写在控件上方,不要只用 placeholder 代替标签
  • 提示文案告诉用户「怎么填」,错误文案告诉用户「哪里错了、怎么改」
  • 选填字段较少时,在标签后标注「(选填)」;必填字段较少时反过来

避免

  • 标签与控件左右并排(中英文长度差异大,容易错位)
  • 提交后只在页面顶部显示「表单有误」,不标出具体字段

无障碍

  • label[for] 与控件 id 一一对应;没有可见标签的控件(如区号下拉)用 aria-label
  • 提示与错误通过 aria-describedby 关联,读屏会在聚焦时读出
  • 提交失败后把焦点移到第一个错误字段

与 v2 的差异

v2 现状规范
错误只把描边变红(invalid prop),没有错误文案和 aria-invalidaria-invalid 驱动样式,并配错误文案
必填星号会被读屏读成「星号」星号加 aria-hidden,控件加 required
提示与控件没有关联使用 aria-describedby