最简方案是单层conic-gradient配合CSS变量:background: conic-gradient(#4a90e2 0deg, #4a90e2 calc(var(--p) 3.6deg), #e0e0e0 calc(var(--p) 3.6deg)),需加border-radius:50%、固定宽高及@supports检测降级。

用 conic-gradient 实现最简圆形进度条
直接用 conic-gradient 配合 background 就能画出带百分比的圆环,不需要 SVG 或 JS 计算角度。关键在于把 0%–100% 映射到 0deg–360deg,并用两层背景遮罩模拟“未完成”部分。
常见错误是写成 conic-gradient(red 0%, red 50%, transparent 50%)——这样会得到硬边切割,且无法响应式更新百分比。
- 用 CSS 变量控制进度:
--p: 75表示 75% - 背景写法:
background: conic-gradient(#4a90e2 0deg, #4a90e2 calc(var(--p) * 3.6deg), #e0e0e0 calc(var(--p) * 3.6deg)) - 必须加
border-radius: 50%和固定宽高(如width: 120px; height: 120px),否则不是圆 - 注意:Chrome 85+、Firefox 83+、Safari 15.4+ 支持;旧 Safari 需用
repeating-conic-gradient曲线兼容
让百分比数字居中并随进度同步更新
纯 CSS 实现数字居中不难,但要让它和进度条视觉对齐、字号适配、避免重叠,得靠定位微调和字体设置。
容易踩的坑是直接用 position: absolute 套在父容器里却不设 position: relative,导致数字飘走;或者用 transform: translate(-50%, -50%) 却忘了父容器没定义宽高基准。
立即学习“前端免费学习笔记(深入)”;
- 容器需设
position: relative - 数字元素用
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) - 推荐用
font-size: clamp(1rem, 4vw, 1.5rem)保证小屏可读、大屏不溢出 - 数字内容建议用
data-pct属性或 JS 注入,CSS 本身不能计算字符串拼接(比如不能自动生成 "75%")
兼容性 fallback:IE 和老版 Safari 怎么办?
conic-gradient 在 IE 完全不支持,Safari 15.3 及更早版本只支持带前缀的 -webkit-conic-gradient,且行为不稳定。这时候别硬扛,该降级就降级。
最务实的做法是检测支持性,用 @supports (background: conic-gradient(red, blue)) 包裹现代写法,外面写一个 SVG fallback 或纯色圆环 + 文字说明。
- SVG fallback 示例:
<svg viewbox="0 0 100 100"><circle cx="50" cy="50" r="45" fill="none" stroke="#e0e0e0" stroke-width="10"></circle><circle cx="50" cy="50" r="45" fill="none" stroke="#4a90e2" stroke-width="10" stroke-dasharray="283" stroke-dashoffset="calc(283 - 283 * var(--p) / 100)"></circle></svg>(283 ≈ 2π×45) - 别用 JS 检测
conic-gradient支持——CSS @supports 更轻量、更可靠 - 如果项目必须支持 IE,直接放弃 CSS 方案,用 SVG + JS 控制
stroke-dashoffset
动画卡顿或跳变的几个关键点
进度条动起来很常见,但一加 transition 就卡、闪、跳,问题往往不在动画本身,而在触发重绘的属性和初始状态。
最典型的是对 background 整体做 transition——浏览器要重绘整个背景图层,性能差;或者没设初始 --p 值,导致从 0 突然跳到目标值。
- 只对
background中的渐变角度部分 transition:transition: background 0.4s ease-out(不是background-color) - 务必在 CSS 中预设默认
--p: 0,JS 更新时用element.style.setProperty('--p', newValue) - 避免在
transform或opacity外的属性上做复杂动画;如需丝滑,考虑用will-change: background提示渲染引擎(慎用) - 移动端要注意:某些安卓 WebView 对
conic-gradient动画支持极差,实测卡顿明显,建议降级为 step 动画或禁用动画
实际项目里,conic-gradient 方案省代码、易维护,但得时刻盯着兼容性和动画表现。真正麻烦的不是怎么画圆,而是当设计要求“进度到 87% 时文字变橙色、圆环加阴影、同时播放音效”——那已经不是 CSS 能单独解决的事了。


















