直接修改 progress 的 value 属性不会触发 css transition 动画,必须通过 javascript 分步更新 value 并为各浏览器伪元素(如 ::-webkit-progress-value、::-moz-progress-bar)单独设置 width 过渡才能实现平滑动画。

直接改 value 属性不会触发 CSS transition 动画,必须用 JavaScript 逐步更新值 + 配合伪元素的 width 过渡才可靠。
progress 元素的 value 变化本身不可过渡
很多人误以为给 <progress></progress> 加上 transition: width 0.3s 就能平滑动画,但这是无效的——value 是 HTML 属性,不是 CSS 可动画属性。浏览器内部渲染进度填充时,并不基于元素自身的 width,而是通过伪元素(如 ::-webkit-progress-value)控制视觉宽度。
- 直接设置
progress { transition: width ... }对动画无作用 -
value突变只会导致填充区域“跳变”,尤其在大跨度更新时(如从 10% → 85%) - 真正可加
transition的是各浏览器私有伪元素的width或transform
必须用伪元素 + transition 才能生效
不同内核浏览器暴露的伪元素不同,需分别处理。只写一种(比如只写 WebKit)会导致 Firefox 或 Safari 下无动画。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- WebKit(Chrome、Edge、Safari):用
progress::-webkit-progress-value - Gecko(Firefox):用
progress::-moz-progress-bar - IE/旧 Edge 不支持
<progress></progress>伪元素动画,建议降级为 div 实现 - 每个伪元素都得单独加
transition: width 0.4s ease-out,不能只写在progress上
progress::-webkit-progress-value {
transition: width 0.4s ease-out;
}
progress::-moz-progress-bar {
transition: width 0.4s ease-out;
}
JavaScript 必须小步更新 value,不能一次性赋值
即使 CSS 写对了,如果 JS 里直接 el.value = 90,浏览器仍会跳变——因为中间没有过渡帧。必须用定时器或 requestAnimationFrame 分步写入。
- 推荐用
requestAnimationFrame控制节奏,比setInterval更精准、更省资源 - 步长建议 ≤ 2%,避免卡顿;例如从 0 → 100,至少分 50 步
- 别忘了检查
max值,避免value超出范围导致异常(如value > max会被截断,但动画可能中断) - 更新前先清除已有动画(如用
el.style.transition = 'none'临时禁用,再恢复),可避免多次触发叠加
自定义 div 进度条反而更可控
当需要兼容老浏览器、或要精确控制颜色渐变/阴影/百分比文字时,原生 <progress></progress> 的限制太多。用 <div class="progress-bar"><div class="fill"></div></div> 结构更灵活。
-
.fill直接用width百分比控制,CSStransition天然生效 - 可自由加
::before/::after显示数字、图标、动画粒子 - 响应式更简单:直接设
width: calc(var(--pct) * 1%)+ CSS 自定义变量驱动 - 无障碍需手动补
aria-valuenow和aria-valuemax
最容易被忽略的是:动画是否在用户切换 Tab 后继续运行。用 requestAnimationFrame 时,页面非激活状态下会暂停,而 setInterval 不会——这会导致进度“卡住”或“突进”。实际项目中得根据场景选调度方式,不能只抄示例代码。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










