Progress Bar:进度条与进度指示
Progress Bar 用一段填充长度表示“已完成多少、还差多少”,对象是一个有终点的任务或目标。它与 Timeline 的区别在于:Timeline 列出有先后顺序的具体事件,进度条只回答比例;它也不是任意数值的图形化,某个量在范围内的位置(评分占比、库存水位)属于 <meter> 的语义,不是进度。
适合与不适合
适合有明确终点且顾客关心距离的场景:距离免运费门槛还差多少、多步骤流程走到第几步、文件上传与内容加载的进展。不适合没有终点的指标、只有单一二元状态(已完成或未完成)的事项,以及没有真实数据支撑、只为制造“快达成了”的心理压力的装饰。
与相邻模式的区别
| 对比对象 | 判据 |
|---|---|
<meter> 量表 | 表达范围内的标量或比例(如各星级占全部评价的比例)。MDN 明确写着 meter 不用于进度条;APG Meter 页也写明不应用它表示加载或任务完成百分比 |
| Timeline | 事件各有名称、时间和状态,读者需要逐项阅读;进度条只表达一个比例,不承载各步骤内容 |
| Badge | Badge 是对象上的简短标签(“新品”“售罄”);进度条描述一个会变化的过程,不当作标签 |
| Countdown Timer | 倒计时表达到某个时间点的剩余时间;进度条表达完成量。二者可以并存,但不要把倒计时画成进度条来暗示紧迫 |
优点与缺点
| 优点 | 缺点 |
|---|---|
| 一眼看出距离终点还有多远 | 仅靠长度难以读出精确值,需要文字补足 |
| 能减轻等待或流程的不确定感 | 假进度或到不了的目标会误导并损害信任 |
原生 <progress> 语义明确,无需自建 | 原生样式跨浏览器差异大,自定义样式易丢语义 |
| 免运费类目标可以驱动凑单 | 若规则与结账不一致,会变成价格承诺问题 |
内容与交互要求
确定与不确定要分开。确定进度已知总量与当前量,用填充比例加文字(“已上传 3 / 5 个文件”);不确定进度只知道“正在进行”,MDN 说明 <progress> 省略 value 即为不确定状态。不确定时不能伪造一个会缓慢爬升的百分比。结束时给出结果文字(完成或失败),不要让进度条停在 99%。
四类场景的口径:
- 免运费门槛:目标是“再买多少可免运费”,分子为当前购物车中计入门槛的金额,分母为门槛。门槛数值、计入范围(折扣前还是折扣后、是否含税)和适用地区必须与结账实际的运费规则来自同一来源,且随市场与币种变化,属于运行时数据,不写成静态文案,见购物车摘要与配送信息。无法核实是否真会免运费时,不显示进度条,改为“运费在结账时计算”。达标后的文字只在结账确实免运费时才写“已免运费”。
- 评分分布条:每档占比是比例,不是进度;文字必须写出档位与数量(“5 星:80 条”),条形只是辅助,见评价展示。各档之和必须等于评价总数。
- 多步骤流程:用有序步骤列表,标出当前步与总步数;条形只是补充。
- 上传与加载:显示已完成量或不确定状态,提供取消入口;失败时留在原位说明并允许重试。
响应式与无障碍
优先使用原生 <progress>:MDN 建议为它提供可访问名称(<label> 或 aria-labelledby / aria-label),标签之间的文本不算可访问名称,只是旧浏览器的回退。自建 role="progressbar" 时,可访问名称必需;aria-valuenow 只在确定进度时提供,不确定时整个省略;aria-valuemin 默认 0、aria-valuemax 默认 100,比例不能直接对应时用 aria-valuetext 给出准确表述。描述页面某个区域的加载时,MDN 建议在被更新的区域设置 aria-busy="true",完成后移除。
不能只靠颜色(WCAG 2.2 SC 1.4.1 Use of Color):填充与未填充部分除颜色外,要有文字或数值。填充色与轨道对必要的图形信息需达到与相邻颜色 3:1 的对比(SC 1.4.11 Non-text Contrast)。进度变化用状态消息通知而不抢焦点(SC 4.1.3 Status Messages;WCAG 提及用 ARIA live region 传达进度条状态),只在有意义的节点播报(达标、失败、完成),不逐个百分点播报。
关于不确定进度的循环动画,SC 2.2.2 Pause, Stop, Hide 说明加载动画在无法交互的阶段可属于必要活动而免于提供暂停机制;仍应在 prefers-reduced-motion: reduce 下降低动效。多步骤中的当前步用 aria-current="step"(MDN 说明用于步骤指示器)。小屏保证文字与条形同屏可见,不因放大文本而截断。
状态与退化
零项:0% 时仍显示文字(“还差 ¥XX 免运费”),不隐藏。一项与多项:多个进度并存(如批量上传)时各自有名称,另给总览。加载与错误:数据未取得时不显示条形,不沿用旧值。目标不可用(如地址变化后不再适用)时撤下进度条。无 JavaScript:服务端输出的静态比例与文字仍可读,只是不会实时更新。减少动态:不确定进度改为静态文字或低幅度提示。
常承载的内容与模块
购物车摘要中的免运费提示(内容来源为配送信息);评价展示的评分分布,评分汇总口径见数据证明;多步骤结账或表单的步骤提示;上传与内容加载。
发布前检查
- 分子、分母与门槛是否与结账实际规则同一来源?
- 确定进度是否有真实数据,不确定进度是否没有伪造百分比?
- 是否有可访问名称与文字值,颜色以外能区分填充?
- 达标、失败、完成是否以状态消息告知而不抢焦点?
- 评分分布是否用 meter 或文字表达,而不是当作进度?
待继续完善
- 各屏幕阅读器对
<progress>、<meter>与aria-valuetext的实际播报未实测。 - 免运费进度在 Shopify 上的可验证实现方式尚缺证据。