必须同时设置value和max才正常显示,仅value不写max会按默认100计算;js更新需校验total>0防nan,用el.value=赋值而非setattribute,ie不支持需fallback,样式须覆盖webkit/firefox三类伪元素。

HTML 原生 <progress></progress> 标签怎么用才不卡死
直接上结论:<progress></progress> 必须带 value 和 max 才能显示进度,缺一个就变空白或默认 0%。它不是靠 JS 驱动的“活”组件,而是纯状态快照——值变了,但没重渲染,看起来就像卡住。
常见错误现象:<progress value="30"></progress> 不写 max,浏览器按默认 max="100" 算,看似正常;但一旦你设 max="200" 却只写 value="30",实际进度只有 15%,而 DOM 里没更新,视觉就“不动”。
-
value必须是数字,且 ≥ 0、≤max;超出范围会被截断,但不报错 - 如果用 JS 动态更新,别只改
.value属性,要确保同时触发重绘(通常赋值后浏览器自动做,但配合requestAnimationFrame更稳) - IE 完全不支持
<progress></progress>,需要 fallback:比如用<div> + <code>aria-valuenow模拟CSS 控制
<progress></progress>样式时哪些伪元素必须写原生
<progress></progress>的样式只能通过伪元素定制,主流浏览器支持三类:::-webkit-progress-bar(外层轨道)、::-webkit-progress-value(填充条)、::-moz-progress-bar(Firefox)。漏掉任一,对应浏览器就会回退到丑陋默认样式。使用场景:想把蓝色填充条改成渐变紫,同时让轨道带圆角和阴影,就得分别写三套规则,不能偷懒只写 WebKit 版。
立即学习“前端免费学习笔记(深入)”;
- Chrome/Edge 必须用
::-webkit-progress-value控制填充色,background生效,width无效(由 value/max 决定) - Firefox 下
::-moz-progress-bar支持background,但不支持border-radius,得靠父容器裁剪 - 所有浏览器都不允许用
:hover直接作用于<progress></progress>内部,要加 wrapper 元素包裹再写
用
<meter></meter>替代<progress></progress>的真实代价<meter></meter>看似更灵活(支持low/high/optimum),但实际项目中几乎没人用——因为语义错位:它表达的是“当前值在某个范围内的相对位置”,比如磁盘使用率 78%(低警戒线 80%,高 95%),而不是“上传完成了 78%”。混用会导致 ARIA 屏幕阅读器误读。性能影响很小,但兼容性坑明显:Safari 一直不支持
optimum的视觉区分,所有值都当普通区间渲染;而且<meter></meter>无法通过 JS 设置 indeterminate 状态(<progress></progress>可以删掉value实现)。- 如果你只是做上传/加载进度,坚持用
<progress></progress>,别为了“看着高级”切<meter></meter> -
<meter></meter>的min/max默认是 0/100,但value超出范围不会报错,只是不渲染填充条 - 服务端返回百分比是小数(如
0.78)时,<progress value="0.78" max="1"></progress>合法,但多数 UI 库会转成整数防歧义
JS 动态更新
<progress></progress>时容易漏掉的边界检查最常踩的坑是:异步任务(比如 fetch 上传)返回的 progress 事件里,
loaded和total可能为 0,直接算Math.round((loaded / total) * 100)会得NaN或Infinity,导致value设为非法值,整个进度条消失。另一个隐形问题:高频更新(比如每 10ms 触发一次)会让重排压力陡增,尤其在低端安卓 WebView 中卡顿明显。
- 务必先判断
total > 0,否则设value = 0保底 - 加节流:用
requestIdleCallback或简单计数(比如每 5 次更新才写 DOM 一次) - 不要用
setAttribute('value', ...)更新,改用el.value = num,前者触发属性监听但不保证视图同步
事情说清了就结束。真正难的不是写对那几行 HTML,而是每次更新前,多想半秒:这个值有没有可能是 NaN?max 变没变?用户用的是不是旧版 Safari?
- Chrome/Edge 必须用










