Hotdry.

Article

构建可访问的错误消息设计系统:从 Design Token 到 ARIA Live Region

错误消息组件化设计系统:设计 token 驱动、i18n 占位符模式、A/B 动态文案灰度、ARIA live region 可访问性实现。

2026-05-13web

在数字化产品中,错误消息是用户与系统交互时最常遭遇的「负面体验节点」。一个设计精良的错误消息系统不仅能降低用户挫败感,还能引导用户快速恢复任务。将错误消息组件化并纳入设计系统(Design System)管理,是保障跨产品体验一致性的关键工程实践。

设计 Token 架构:错误消息的视觉基石

设计 Token 是设计系统中最小的原子单位,错误消息组件的视觉表现完全依赖 Token 驱动。核心 Token 层级应包含颜色语义、字体规格、间距基线与图标语义四类。

颜色 Token 不应直接映射 HEX 值,而应使用语义化命名。错误状态的背景色建议定义为 color.feedback.error.background(如十六进制 #FEF2F2),错误文本对应 color.feedback.error.text(如 #991B1B),错误边框对应 color.feedback.error.border(如 #FCA5A5)。这种间接映射使得主题切换(明 / 暗模式)时错误状态自动适配,无需为每个错误场景单独处理颜色。

字体 Token 需覆盖错误消息的字号、行高与字重。标题级错误(如「操作失败」)建议使用 typography.scale.error.title;内联字段错误建议使用 typography.scale.error.inline;提示性错误建议使用 typography.scale.error.hint。字重统一使用 fontWeight.regular(400),避免粗体加重负面情绪感知。

间距 Token 应定义错误消息与上下元素的间距基线。推荐以 4px 为基准网格,错误容器内边距设为 space.inset.error.md(16px),消息与操作按钮间距设为 space.stack.error.action(12px),图标与文本间距设为 space.inline.error.icon(8px)。

图标 Token 建议定义错误级别对应的图标风格。严重错误使用 icon.error.critical(实心圆圈加感叹号),表单验证错误使用 icon.error.validation(三角警告),网络错误使用 icon.error.network(断开的圆环)。图标尺寸应与字号保持视觉平衡,16px 字号对应 16px 图标,14px 字号对应 12px 图标。

i18n 占位符模式:动态内容的本地化策略

错误消息中的动态内容(用户名、文件数量、操作时间等)必须通过占位符注入,而非硬编码拼接。推荐采用 ICU MessageFormat 标准实现占位符管理,该标准被 Flutter intl、react-intl、vue-i18n 等主流国际化库广泛支持。

基础语法结构为 {placeholderName, type, format}。复数占位符示例:{count, plural, one {# 个文件已删除} other {# 个文件已删除}}。选择占位符示例:{errorType, select, network {网络连接失败,请检查网络设置} validation {输入格式不正确} other {操作失败}}。数字占位符示例:{size, number} MB 已超过最大限制

在设计系统中,错误消息的翻译文件应包含完整的占位符元数据。以 ARB 文件为例,消息定义需附带 description 字段说明用途,以及 placeholders 字段声明占位符类型:

{
  "form.error.fileSizeExceeded": {
    "message": "{count, plural, one {文件大小超出限制} other {{count} 个文件大小超出限制}}",
    "description": "当上传文件超过允许大小时显示的错误消息",
    "placeholders": {
      "count": {
        "type": "int",
        "format": "decimal"
      }
    }
  }
}

占位符命名应使用业务含义而非技术变量,如 fileSize 而非 sizeremainingTime 而非 time。占位符类型必须严格匹配:数字使用 intdouble,文本使用 String,日期使用 DateTime。类型不匹配会导致翻译工具报错或运行时渲染异常。

文本扩展率是需要额外关注的本地化问题。德语翻译平均比英语长 20%,法语长 15%,中文平均缩短 30%。错误消息容器的 max-width 应使用相对单位(如 ch)或设置足够宽松的固定宽度,并通过 overflow-wrap: break-word 防止文本溢出。阿拉伯语等 RTL(从右到左)语言需单独测试文本对齐与图标翻转。

A/B 动态文案灰度:数据驱动的文案优化

错误消息的措辞直接影响用户的后续行为转化。通过 A/B 测试灰度发布不同文案变体,可以基于真实用户行为数据迭代最优表达。

文案变体建议遵循控制变量原则。变量可以是语气(正式 / 友好)、结构(先说原因再说建议 / 先说建议再说原因)、长度(精简 / 详细)。每次测试仅改变一个变量,以归因具体因素对转化率的影响。

A/B 测试的基础指标应包括:错误消息出现后的任务完成率、用户放弃率、客服工单创建率。正向指标期望提升,负向指标期望下降。统计显著性阈值推荐设为 95%,最小样本量需根据基线转化率计算(可通过功效分析工具估算)。

灰度发布策略建议采用「先小后大」的分阶段放量:初期选取 5% 流量验证稳定性,中期扩至 20% 收集足够样本,后期全量上线。对于高风险场景(如支付失败消息),可保留原版作为回滚备选,通过 Feature Flag 控制流量分配。

ARIA Live Region:可访问性的技术实现

屏幕阅读器用户依赖 ARIA Live Region 感知动态内容变化。错误消息作为页面状态的非焦点变化,必须通过 Live Region 显式声明,否则屏幕阅读器将无法朗读新增的错误提示。

基础实现为在错误消息容器上添加 role="alert" 属性。该属性隐式设置 aria-live="assertive"aria-atomic="true",意味着错误消息会立即中断当前朗读并完整播报其内容。适用于严重错误(如提交失败、权限不足)。

<div role="alert" class="error-message">
  <svg aria-hidden="true" class="error-icon">...</svg>
  <p>文件大小超出限制,请选择 10MB 以内的文件</p>
</div>

对于表单内联验证错误,建议使用 aria-describedby 将错误消息关联到对应输入框,而非使用 Alert Role。内联验证使用 role="status"(隐式 aria-live="polite"),消息会在用户完成当前字段输入后、切换到下一字段时播报,不打断用户正在进行的输入流程。

<label for="email">邮箱地址</label>
<input type="email" id="email" aria-describedby="email-error" />
<span id="email-error" role="status" class="field-error">请输入有效的邮箱格式</span>

图标必须添加 aria-hidden="true",防止屏幕阅读器将图标内容朗读为无意义字符。所有错误消息的颜色不能作为唯一信息载体,需配合图标或文本共同传达错误语义。键盘导航场景下,严重错误出现时应自动聚焦到错误消息区域,通过 tabindex="-1"focus() API 实现。

实战参数清单

构建错误消息设计系统的核心参数如下:

Token 层级参数:错误背景色 #FEF2F2,错误文本色 #991B1B,错误边框色 #FCA5A5;标题错误字号 16px/1.5,行高比例 1.5;内联错误字号 14px/1.4;图标尺寸与字号 1:1。

i18n 参数:占位符类型必须显式声明;文本容器 max-width: 42ch;RTL 语言需单独测试;翻译文件必须包含 description 与 placeholders 元数据。

A/B 测试参数:每次仅测试单一变量;显著性阈值 95%;放量节奏 5%→20%→100%;高风险场景保留原版作为回滚策略。

ARIA 参数:严重错误使用 role="alert";内联验证使用 role="status";所有图标添加 aria-hidden="true";错误消息通过 aria-describedby 关联表单元素。

通过设计 Token 统一视觉规范、i18n 占位符保障本地化质量、A/B 测试优化文案表达、ARIA Live Region 实现无障碍支持,这四个维度的协同才能构建真正工程化的错误消息设计系统。

资料来源:Wix Studio Blog「How to design error messages for humans」与设计系统本地化最佳实践。

web

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com