用width+transition实现进度条动画需设子元素width从0%到100%、display:block、overflow:hidden;高性能方案用transform:scalex()配合transform-origin:left,避免重排卡顿。

用 width + transition 实现基础填充动画
最直接的方式是控制一个子元素的 width 从 0% 到 100%,配合 transition 实现平滑变化。父容器设为固定高度和背景色,子元素用 background-color 填充,overflow: hidden 防止溢出。
关键点在于:必须给子元素设置 display: block(默认 inline 时 width 不生效),且过渡属性要写在子元素上,而不是父容器。
.progress-bar {
height: 8px;
background-color: #e0e0e0;
overflow: hidden;
}
.progress-fill {
height: 100%;
background-color: #4caf50;
width: 0%;
transition: width 0.3s ease;
display: block;
}
然后通过 JS 修改 progress-fill 的 style.width,或切换 class 触发动画。
用 @keyframes + transform 替代 width 更高性能
频繁修改 width 会触发重排(layout),尤其在低端设备或复杂页面中可能卡顿。改用 transform: scaleX() 只影响合成层,浏览器能走 GPU 加速。
注意:scaleX() 是相对于元素自身宽度缩放,所以需把子元素初始宽度设为 100%,再用 transform 缩放到目标比例。
- 初始状态:
transform: scaleX(0) - 完成状态:
transform: scaleX(1) - 动画必须加
transform-origin: left,否则会从中心缩放
@keyframes fill-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
.progress-fill {
width: 100%;
transform-origin: left;
animation: fill-progress 2s ease forwards;
}
JS 控制进度时避免重复触发或跳变
如果用 JS 动态更新进度(比如轮询接口返回值),直接反复设置 style.transform 或 style.width 容易导致动画中断、回退或跳帧。
推荐做法是:只在进度有实质性变化(比如变化 ≥ 1%)时才更新,且用 requestAnimationFrame 批量合并操作。
- 不要每 100ms 都调
el.style.width = `${percent}%` - 用
el.classList.remove('animating')+el.offsetWidth强制重绘后再加 class,确保动画重播 - 若需暂停/恢复,
animation-play-state: paused比直接改width更可靠
兼容性与移动端适配要注意的细节
IE10+ 支持 transition 和 @keyframes,但 IE 对 transform-origin 的解析有偏差——必须写成 transform-origin: 0 0 而非 left,否则缩放中心偏移。
移动端 Safari 在某些 iOS 版本下,对 scaleX() 动画的渲染有轻微闪烁,可加 will-change: transform 提前提示优化,但别滥用,否则反而增加内存开销。
另外,height 设太小(如 2px)在高清屏上可能被像素对齐抹掉,建议至少设 4px 并搭配 transform: scaleY(1) 确保清晰。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











