EN
展现形式 · 概念

Toast:瞬时反馈与状态提示

说明 Toast 如何承载加购成功、已复制、保存失败等瞬时反馈及页内状态提示,依据 APG Alert、ARIA live regions 与 WCAG 2.2.1、4.1.3 讨论 role 选择、停留时间、错误就近保留与多条排队。

Toast 是在页面角落短暂出现、不打断当前操作的反馈条,告知刚发生的事:已加入购物车、已复制链接、已保存偏好。它回答“我刚才的操作成功了吗”,不承载需要顾客决定或必须读完的信息;后者应使用页内文字、Banner 或 Modal。页面里长期存在的状态文字(如表单顶部的错误摘要)同属状态提示,可用相同的 live region 技术,但不应消失。

适合与不适合

适合低风险、可自行核对的确认:加购成功、复制成功、收藏成功、后台保存完成。不适合错误详情、需要点击的操作(撤销除外)、价格或库存变化、政策变更,以及顾客必须知道才能继续的信息。“保存失败”类错误要就近保留在出问题的位置,Toast 最多作为附加提醒。

与相邻模式的区别

相邻模式判据说明
Banner触发者与是否消失Banner 承载全站或区域级的持续消息;Toast 只回应一次具体动作并会消失
Modal是否要求处理Modal 阻断背景并要求处理;Toast 不夺取焦点。需要打断工作流时,APG 建议用 Alert Dialog
Popover触发者与位置Popover 由用户对元素的操作触发并就近显示;Toast 由系统事件触发,位置固定
Inline Form 的页内反馈是否就近常驻字段错误与提交结果留在表单内;Toast 只能补充,不能替代

优点与缺点

优点缺点
不打断流程,反馈及时消失后无法找回,容易漏看
占用空间小,位置统一多条并发时堆叠并遮挡内容
可被读屏软件朗读而不抢焦点朗读依赖 live region 的创建时机,误用则完全无声

内容与交互要求

文字简短并写明结果与对象,例如(虚构示例)“已将 M 码黑色加入购物车”,不只写“成功”。失败时写明原因与下一步:Shopify Ajax Cart API 库存不足时返回 422,响应含 status、message、description 字段(核验于 2026-09-29,shopify.dev Cart API 参考页),可把 description 转成顾客能理解的文字,展示在加购按钮附近。撤销是 Toast 上少数合理的操作,但窗口过短时必须另有恢复路径。

多条并发时:同类连续反馈(连续加购)合并为一条并更新数量,异类按顺序排队,同时可见条数设上限。位置避开固定栏与软键盘(见 Sticky Bar)。

响应式与无障碍

MDN 的 ARIA live regions 指南:aria-live 取 off、polite、assertive,polite 最常用,assertive 会打断当前朗读,应少用;role="status" 隐含 polite,role="alert" 用于错误与警告,二者本身就是 live region 角色。MDN 建议对 status 加冗余 aria-live="polite",并避免对 alert 同时加 aria-live(VoiceOver iOS 会重复朗读)。live region 必须在内容变化前已存在于 DOM:先渲染空容器,稍后再写入文字。

WCAG 2.2 的 4.1.3 Status Messages(AA)要求状态消息能通过 role 或属性被辅助技术呈现且不必获得焦点;其页面示例把成功与应用状态对应 role="status",把警告与错误对应 role="alert"。APG 的 Alert 模式要求警告不得影响键盘焦点,并建议避免自动消失的 alert:页面写明消失过快可能导致无法满足 WCAG 的 2.2.3 No Timing(AAA,该标准在 WCAG 2.2 中仍然存在;页面引用的是 WCAG 2.0 的编号),频繁打断也会妨碍视觉与认知障碍用户。

停留时间:WCAG 2.2 的 2.2.1 Timing Adjustable(A)要求存在时限时至少满足其一:用户能在遇到前关闭时限;能调整到默认值的十倍以上;或到期前收到警告并至少有 20 秒用简单动作延长;实时事件、必要与超过 20 小时为例外。Toast 自动消失是否算这里的“时限”,标准没有逐条结论;稳妥做法是:只用 Toast 承载可丢失的确认、提供关闭按钮、悬停与聚焦时暂停计时、让重要信息另有常驻位置。具体秒数没有标准值,文字越长越要延长,不要只套用默认的几秒。2.2.2 Pause, Stop, Hide 要求自动更新且与其他内容并行呈现的信息提供暂停、停止或隐藏机制。

MDN 的 Popover API 页面把自定义 toast 列为该 API 的典型用途;popover 始终非模态,popover="manual" 不会被点击外部关闭,显隐由脚本管理。

状态与退化

  • 零项:无待显示消息时保持空的 live region,不渲染可见容器。
  • 一项与多项:单条自然显示;并发时合并同类、排队异类并限制条数。
  • 加载:长任务用进度或加载状态,不用连续 Toast。
  • 错误:就近显示并常驻直到解决;表单错误用 role="alert" 或错误摘要并关联到字段。
  • 无 JavaScript:反馈通过刷新后页面上的文字呈现,不依赖瞬时元素。
  • 减少动态:取消滑入与淡出,直接显示与移除。

常承载的内容与模块

加购确认(Horizon 购物车说明了即时反馈与最终购物车应分开验证,购买流程说明了提交行为的职责边界)、复制优惠码或链接、保存偏好。文案与时机由具体模块决定,展现层只负责呈现;总览见功能模块。

发布前检查

  • 这条信息丢失后顾客会做出错误决定吗?若会,不应使用 Toast。
  • 错误是否就近常驻,而不是只在 Toast 里闪一下?
  • live region 是否在内容变化前已存在?role 与 aria-live 是否重复?
  • 停留时间能否暂停、关闭?多条并发是否合并或排队?是否遮挡固定栏或软键盘?
  • 无 JavaScript 与减少动态设置下是否仍有可见反馈?

固定版本主题实现

固定基线为 Dawn v15.3.0 与 Horizon 4.2.0;结论限于这两个提交,均为静态源码分析,未运行验证。

待继续完善

  • 在读屏软件中测试 status 与 alert 在不同浏览器下的朗读时机与打断行为。
  • 补充加购失败、库存变化与撤销的完整反馈流程。