html原生元素需手动更新value属性,不自动感知异步操作;适用于已知总步数与当前进度的场景,支持max自定义、indeterminate模式及跨浏览器css伪元素样式控制。

HTML原生<progress></progress>元素能直接用,但别指望它自动更新
浏览器自带的 <progress></progress> 是个纯展示控件,它不感知任何异步操作——你得自己调用 value 属性去改。常见错误是写完 <progress value="0"></progress> 就以为“会动了”,结果页面加载完它还卡在 0%。
适用场景很明确:你知道总步数和当前进度(比如文件分片上传、表单多步提交),且不需要自定义样式或动画细节。
-
max默认是 100,但可以设成任意正整数(比如总文件大小为 128456 字节,就设max="128456") - 如果
value未设置或为负值,进度条显示“不确定状态”(浏览器渲染为动画条纹,类似<meter></meter>的 indeterminate 行为) - IE 不支持
<progress></progress>,Edge 12+ 才开始支持;如需兼容旧版,必须降级为<div> + CSS 模拟 <h3>用 JavaScript 控制 <code><progress></progress>时,别在循环里直接赋值想模拟“加载中”,有人写
for (let i = 0; i ,结果进度条一闪而过——因为 JS 是单线程,DOM 更新被批量合并,浏览器只在脚本执行完才重绘。正确做法是把更新节奏交给浏览器调度:
- 用
setTimeout或requestAnimationFrame分帧更新(适合教学演示) - 真实场景中,应绑定到实际异步事件:XMLHttpRequest 的
onprogress、Fetch 的ReadableStream、或者 Promise 链中每个步骤完成后的回调 - 注意防抖:上传大文件时,
onprogress可能每毫秒触发多次,建议用时间间隔(如 50ms)或进度变化阈值(如 ≥1%)做节流
示例(简化版 fetch 上传进度):
fetch('/upload', { method: 'POST', body: fileBlob }).then(r => r.json()) .then(data => { progressEl.value = 100; // 最终置满 });⚠️ 这段代码本身不带进度——要加进度,得用
XMLHttpRequest或Upload.upload()类库,原生 Fetch 目前不暴露上传进度(只有下载可用response.body.getReader())。CSS 自定义
<progress></progress>样式,伪元素名容易写错Chrome/Edge/Firefox 对
<progress></progress>的样式控制都依赖伪元素,但各浏览器前缀和名称不统一:- WebKit 内核(Chrome/Safari):用
progress::-webkit-progress-bar和progress::-webkit-progress-value - Firefox:用
progress::-moz-progress-bar - 全局通用(现代标准):用
progress::progress-bar和progress::progress-value(目前仅实验性支持)
最稳妥的写法是同时写三套规则,且注意顺序:WebKit 规则必须放在最后,否则会被 Firefox 规则覆盖(因为选择器权重相同,后声明者生效)。
另外,
height必须在<progress></progress>元素自身上设,伪元素里的height无效;颜色控制也得分开:背景色在::-webkit-progress-bar,填充色在::-webkit-progress-value。不确定加载状态,优先用
<progress></progress>的 indeterminate 模式而非自己画旋转动画当无法预估耗时(比如发起一个 API 请求,不知道要 200ms 还是 8s),不要强行塞个从 0 到 100 的假进度条——用户会误判剩余时间,反而更焦虑。
- 直接省略
value属性:<progress max="100"></progress>,浏览器自动进入不确定模式(条纹滚动动画) - 比手写
@keyframes spin更轻量,无额外 CSS/JS 开销,语义正确,还自带可访问性(屏幕阅读器会读作“正在处理”) - 如果设计稿强制要求品牌色旋转图标,再考虑 SVG +
transform: rotate(),但请确保同时提供aria-busy="true"和禁用相关按钮
真正难的不是让进度条动起来,而是判断什么时候该动、动多快、动到哪——这取决于你对后端响应节奏、网络波动、用户预期的理解。样式和语法只是最后一层皮。
- 用











