<progress>标签仅适用于“正在发生的、有明确起点和终点的任务”,如文件上传或视频播放;用于静态快照(如CPU使用率、心率)属语义错误,应改用<meter>。

progress 必须关联“正在发生的任务”,否则语义错误
如果你要表达的不是「某件事正在推进、且有明确起点和终点」,就别用 <progress>。比如服务器响应延迟 42ms、用户积分等级 8500、API 调用成功率 99.2%——这些都不是任务,只是快照状态。<progress value="42"> 会被屏幕阅读器读成“进度 42%”,造成严重歧义。
常见误用场景:
- 单独展示 CPU 使用率:
<progress value="75" max="100">→ 应换<meter> - 渲染心率实时数据(68 bpm)→
<progress>暗示“这任务还没完”,但心率不是任务 - 用
value="-1或value="abc"触发 indeterminate 状态 → 不可靠,应直接省略value属性
真正该用 <progress> 的只有:文件上传、表单提交、视频播放进度、批量作业执行中——这些都有可预期的完成点。
meter 的 low/high/optimum 不是装饰,缺一不可
<meter> 的 low、high、optimum 不是 CSS 开关,而是向辅助技术传递业务判断的关键信号。只写 <meter value="85" min="0" max="100">,AT 工具只会读出“85”,完全丢失“偏高”“远离理想值”的含义。
立即学习“前端免费学习笔记(深入)”;
必须满足约束链:min ≤ low ≤ optimum ≤ high ≤ max。违反时:
- Chrome 静默丢弃越界属性(比如
optimum="0"但low="30") - Firefox 可能报错或渲染异常
- 省略
low和high,浏览器按(min + max) / 2自动分段,但不可控、不明确
例如磁盘使用率监控:<meter value="85" min="0" max="100" low="20" high="80" optimum="50"> 才能准确传达“已超预警线,且偏离最优水位”。
动态更新时,element.value = N 比 setAttribute('value', 'N') 更可靠
用 JavaScript 更新进度或度量值时,直接赋值比操作 DOM 属性更稳妥:
-
progressEl.value = 65→ 触发重绘、无障碍播报、伪元素同步 -
progressEl.setAttribute('value', '65')→ 旧版 Safari 可能卡住不动,Chrome 有时不触发样式重算 - 同理适用于
<meter>,尤其在频繁更新传感器数据时
注意:value 必须是数字,不能带单位或百分号;value="85%" 或 value="65px" 会被浏览器忽略。
自定义样式只能靠伪元素,且前缀不能省
直接写 progress { background: blue; } 完全无效——<progress> 和 <meter> 内部结构由浏览器私有实现,只能通过伪元素穿透:
- WebKit 内核(Chrome/Safari):
progress::-webkit-progress-bar、progress::-webkit-progress-value - Gecko 内核(Firefox):
progress::-moz-progress-bar - 伪类状态也不同:
meter[value>high]在 Firefox 中支持有限,meter:out-of-range更通用
实际项目中,若需强一致性控制(比如统一配色、动画、交互),多数团队会退回到 <div> + ARIA 模拟——原生标签的样式自由度太低,且跨浏览器渲染差异大。



















