最可靠纯CSS进度条用linear-gradient配合background-position动画实现,通过background-size:200%和calc(--progress*1%-100%)动态控制填充位置,兼顾性能与兼容性。

用 linear-gradient 模拟进度填充动画最可靠
纯 CSS 进度条动画不依赖 JS,核心是让“已加载”部分看起来在增长。直接操作 width 动画会有重排开销,且无法实现渐变色填充;而用 linear-gradient 配合 background-position 或 mask 控制可见区域,性能更好、兼容性也够用(Chrome 26+/Firefox 16+/Safari 6.1+)。
推荐做法:固定背景图尺寸,通过移动背景位置暴露不同宽度的色块,再用 animation 驱动 background-position 变化。示例:
.progress-bar {
height: 8px;
background-color: #e0e0e0;
background-image: linear-gradient(90deg, #4caf50 0%, #4caf50 50%, transparent 50%);
background-size: 200% 100%;
background-position: 100% 0;
animation: fill 2s ease-out forwards;
}
<p>@keyframes fill {
to { background-position: 0 0; }
}-
background-size: 200% 100%让渐变图铺满两倍宽度,初始时只显示右半(即 0% 进度) -
background-position: 100% 0起始位置靠右,to移到0 0即左对齐,视觉上绿色从左向右“长出来” - 动画结束停在
forwards,避免回弹;若需动态控制进度,改用 CSS 自定义属性 +calc()更灵活
用 CSS 自定义属性动态控制进度值
硬编码动画只能做固定进度,实际项目常需 JS 注入数值(比如上传进度)。这时不要改 width,而是把进度映射到 background-position 的计算值上:
.progress-bar {
--progress: 0;
background-position: calc(var(--progress) * 1% - 100%) 0;
}这样 JS 只需更新 element.style.setProperty('--progress', 65),CSS 就自动算出对应位置。注意两点:
立即学习“前端免费学习笔记(深入)”;
- 必须设
background-size: 200% 100%才能保证 0–100% 映射到 -100% → 0 的位移范围 - Safari 对
calc()在background-position中的支持较晚(iOS 15.4+),旧版需降级为 JS 控制width+overflow: hidden
IE11 兼容方案:用 clip-path + width 回退
IE11 不支持 background-position 动画和 clip-path 的 inset(),但支持 width 动画和简单 clip。可这样写:
.progress-bar::before {
content: '';
display: block;
height: 100%;
width: 0%;
background: #4caf50;
animation: fill-width 2s ease-out forwards;
}
<p>@keyframes fill-width {
to { width: 100%; }
}关键点:
- 用伪元素
::before填充,父容器设overflow: hidden截断超出部分 - IE11 不支持
background-image动画,所以不能依赖渐变背景;单色填充足够满足多数场景 - 若必须 IE11 下显示渐变,得用 SVG 内联或 base64 图片作背景,但体积和维护成本明显上升
动画卡顿?检查是否触发了 layout 或 paint
看似简单的进度条,实际容易因 CSS 属性选择不当导致掉帧。常见陷阱:
- 用
transform: scaleX()动画虽高效,但会拉伸内容(包括文字、图标),除非容器内只有纯色块,否则视觉异常 -
width动画强制浏览器每帧重排(reflow),尤其在中低端安卓 WebView 中明显卡顿 -
background-position和mask-position是合成层属性,GPU 加速友好,优先选它们 - 如果进度条嵌套在频繁重绘的区域(如滚动列表项),建议加
will-change: background-position提前提示浏览器优化
真正难的不是写出动画,而是让动画在各种设备、各种嵌套层级下都稳住 60fps——往往要反复验证 background-position 和 mask 的组合在目标环境中的表现。



















