应优先使用原生 标签而非手写 div+js;必须同时设置 value 和 max 才显示确定进度,max 默认为 1 但建议显式声明;value 需为数字且在 [0, max] 范围内;js 更新须直接赋值数字,不可用字符串;css 定制需通过伪元素并重置 appearance: none;辅助功能需依赖 aria-label 和 aria-live,不可靠 innerhtml 或颜色传达状态。

直接用 <progress></progress> 标签,别手写 div + JS 模拟——除非你要支持 IE11 或需要像素级动画控制。
必须同时设 value 和 max 才显示确定进度
只写 <progress></progress> 或只设 value,浏览器会进“不确定”状态(条纹动画),这不是 bug,是规范行为。它不表示“正在加载”,只是告诉你“进度未知”。
-
max默认是1,但显式写上更安全,尤其当后端返回小数时(比如value="0.72") -
value必须是数字,且 ≥ 0、≤max;超出范围会被自动截断(value=120、max=100→ 显示满格) - 不要省略
max:封装 React/Vue 组件时,漏传max是最常见空白条原因
JS 更新 value 必须赋值数字,不能用字符串
progress.value = "50" 不触发重绘,进度条不动;progress.setAttribute('value', '50') 也无效——它只改 HTML 属性,不更新 DOM 的 value 值。
- 从
<input type="number">读值后记得Number(input.value)或+input.value - 用
fetch上传时,从XMLHttpRequest.upload.onprogress的event.loaded / event.total算出百分比,再转成整数填入bar.value - 不要在循环里频繁设
value(如每 10ms 一次),浏览器有渲染节流,建议间隔 ≥ 50ms
CSS 自定义必须靠伪元素,各浏览器写法不同
progress 本身不渲染文本,也不能用 color 或 background-color 直接改填充色。WebKit/Firefox 都要单独处理,且 IE 完全不支持伪元素定制。
- 先写
appearance: none,否则 WebKit 下伪元素不生效 - Chrome/Safari 用
progress::-webkit-progress-bar控轨道,progress::-webkit-progress-value控填充 - Firefox 只认
progress::-moz-progress-bar,不支持分开设轨道/填充色 - 别给
progress设font-size——它不显示文字,这个属性没意义
辅助文本和可访问性不能靠 innerHTML
<progress value="70">70%</progress> 中的 “70%” 默认不可见,也不能被屏幕阅读器识别为进度值。它只是 fallback 内容,仅当浏览器完全不支持 progress 时才显示。
- 用
aria-label或aria-labelledby明确任务类型,例如:<progress value="70" max="100" aria-label="文件上传进度"></progress> - 旁边放一个同步更新的
<span></span>,并加aria-live="polite",让屏幕阅读器播报变化 - 避免仅用颜色表达状态(比如“红色=失败”),色觉障碍用户看不到区别
真正容易被忽略的是:progress 不是 loading 动画替代品,也不该用来显示磁盘使用率这类静态度量——前者该用 <div role="progressbar" aria-valuetext="加载中"> + CSS 动画,后者该用 <code><meter></meter>。











