最简方案是用conic-gradient配合CSS变量--p:background: conic-gradient(#4a90e2 0deg, #4a90e2 calc(var(--p)3.6deg), transparent calc(var(--p)3.6deg)),需设border-radius:50%、固定宽高、background-clip:content-box及from -90deg对齐顶部。

用 conic-gradient 实现环形进度条最简方案
现代浏览器(Chrome 69+、Firefox 85+、Safari 15.4+)直接支持 conic-gradient,它是实现环形进度条最轻量、最可控的方式。不需要 SVG、不依赖 JS 计算角度,纯 CSS 就能驱动动态填充。
关键在于:把圆心角映射为 0–360deg,用渐变色“裁剪”出当前进度段,再配合 background-clip: text 或遮罩层露出有效区域。
常见错误是直接写 conic-gradient(from 0deg, #4a90e2 0%, #4a90e2 50%, transparent 50%)——这只能做静态半圆,动不了;真正可驱动的写法必须把结束角度设为变量,并用 animation 或 @property 控制。
- 推荐用 CSS 自定义属性
--p表示百分比(0–100),再在conic-gradient中换算成角度:calc(var(--p) * 3.6deg) - 必须设置
background-size: 200% 200%配合background-position: center,否则动画缩放会错位 - 为兼容 Safari,避免用
from关键字,改用显式起始色:例如conic-gradient(#4a90e2 0deg, #4a90e2 calc(var(--p) * 3.6deg), transparent calc(var(--p) * 3.6deg))
IE/旧版 Edge 下 fallback 到 stroke-dasharray SVG 方案
当项目仍需支持 IE11 或旧版 Edge(≤18),conic-gradient 不可用,就得退回 SVG + stroke-dasharray。这不是“备选”,而是必须存在的降级路径。
立即学习“前端免费学习笔记(深入)”;
核心逻辑是:固定一个圆形 <circle> 的周长(比如 251.2,对应 r=40 的 2πr),再用 stroke-dasharray="251.2, 251.2" 把描边拆成“实线+空白”两段;通过改变第一段长度模拟进度。
- JS 控制时,更新
circle的stroke-dashoffset更直观:比如offset = 251.2 * (1 - p/100) - CSS 动画只能靠
@keyframes驱动stroke-dashoffset,但无法响应实时数据变化,适合固定加载动画 - 务必给
<svg>设置viewBox="0 0 100 100"并移除宽高硬编码,否则在不同容器中会拉伸变形
@property 驱动 conic-gradient 动画的兼容性陷阱
想让 --p 变量参与 CSS 动画(比如从 0 → 100),必须声明 @property,否则 Chrome/Firefox 会静默忽略动画——这是最容易被跳过的一步。
声明时要注意三点:类型必须是 <number>,初始值不能缺,且作用域要覆盖到使用该变量的选择器。
- 正确写法:
@property --p { syntax: '<number>'; inherits: false; initial-value: 0; } - 如果漏掉
syntax,动画不触发;如果写成<length>或<percentage>,计算会失败 - Firefox 目前不支持
@property,所以带变量动画的方案在 Firefox 中会退化为静态(显示初始值),需额外用 JS 注入 style 或用媒体查询隔离
环形条视觉细节:如何避免“断点”和“抖动”
无论用哪种方案,最终呈现常出现两个肉眼可见问题:进度衔接处有细缝(断点),或旋转时边缘轻微锯齿(抖动)。它们不是 bug,而是渲染机制导致的,但可以缓解。
- 断点源于渐变色边界对齐误差,加
background-color: #fff(与底色一致)并设置border-radius: 50%容器,能掩盖接缝 - 抖动多发生在低 DPI 屏幕或缩放非 100% 时,给元素加
transform: translateZ(0)强制 GPU 加速,比单纯用will-change: transform更稳定 - 不要用
border-radius: 50%+border模拟环形条——圆角描边在不同浏览器下接头处理不一致,必出断点
复杂点不在代码行数,而在各方案的边界条件:你得清楚当前项目要支持哪些浏览器、是否需要 JS 实时控制、能否接受 Safari 下无动画。这些决定一上来就锁死了技术选型,没法后期补救。


















