progress标签需正确设置value和max属性才能显示确定进度,否则进入不确定态;更新value必须用DOM属性赋值而非setAttribute或innerHTML;自定义样式需重置appearance并使用对应浏览器伪元素;无障碍需配合aria-label或aria-live。

progress 标签不会自动动起来,它只响应 value 和 max 属性变化;不设 value 就是“不确定状态”,浏览器画动画条纹,不是进度。
为什么progress没显示或卡在0% / 100%
常见原因不是样式问题,而是属性值非法:
-
value缺失、为负数(如-1)、或大于max(如value="105" max="100")→ 浏览器静默丢弃该值,进度条退回到不确定态或截断为满格 - 只写
<progress max="100"></progress>→ 没value,就是不确定态,不显示数字进度 -
value或max是字符串(如"50")→ 多数浏览器会转数字,但 Firefox 对非数字字符串更敏感,可能失效 - IE11 及更早版本完全不支持
progress,页面上直接消失
用 JavaScript 更新 value 的正确姿势
必须走 DOM 属性赋值,不能靠 HTML 属性或 innerHTML:
- ✅ 正确:
bar.value = 42(数字类型)或bar.value = Math.round(loaded / total * 100) - ❌ 错误:
bar.setAttribute('value', '42')—— 不触发 UI 更新 - ❌ 错误:
bar.innerHTML = '<progress value="42"></progress>'—— 替换整个节点,丢失引用和事件绑定 - 更新前建议加校验:
if (val >= 0 && val - 高频更新(如每 10ms)易掉帧,建议加阈值:仅当
Math.abs(val - bar.value) >= 1再赋值
CSS 自定义填充色必须用伪元素,且要重置 appearance
直接写 progress { background: red } 只改外框,填色部分完全无效:
立即学习“前端免费学习笔记(深入)”;
- 先统一禁用默认外观:
progress { -webkit-appearance: none; -moz-appearance: none; appearance: none; } - Chrome/Safari:
progress::-webkit-progress-bar控轨道,progress::-webkit-progress-value控填充 - Firefox:
progress::-moz-progress-bar控填充(不区分轨道/填充,整体着色) - 不要给
progress设font-size或color—— 它不渲染文本内容 - 想加平滑过渡?Chrome/Safari 支持
transition: width 0.3s ease在::-webkit-progress-value上,Firefox 不支持 width 动画,靠重绘帧模拟
无障碍支持不能只靠默认行为
progress 原生带 role="progressbar",但屏幕阅读器是否读出“65%”取决于你有没有同步好上下文:
- 必须配
aria-label或aria-labelledby,例如:<progress value="65" max="100" aria-label="图片上传进度"></progress> - 别把提示文字塞进标签体:
<progress>65%</progress>中的 “65%” 是 fallback 内容,仅旧浏览器降级时可见,不被读屏识别 - 旁边放一个实时同步的
<span aria-live="polite">已上传 65%</span>,确保语音播报及时 - 避免单靠颜色表达状态(如红=失败),色觉障碍用户无法识别
真正难的不是让进度条动起来,而是业务中“100%”的定义是否一致——上传三个文件,大小分别是 1MB、100MB、5MB,按数量算 2/3 ≠ 进度 66%,得按字节加权。这个逻辑 JS 得自己写,progress 只负责忠实反映你给它的那个数字。



















