SVG圆环进度条本质是用的stroke-dasharray(设为周长,如283,0)与stroke-dashoffset(从283递减至0)协同实现,配合rotate(-90)对齐顶部,仅对stroke-dashoffset做CSS过渡动画,确保进度平滑、方向正确、起点精准。

用 stroke-dasharray 和 stroke-dashoffset 控制 SVG 圆环进度
环形进度条本质是 SVG 的 元素配合描边虚线属性实现的,不需要 JS 或第三方库。核心是把圆周长转为虚线总长,再用 stroke-dashoffset 推动“空白段”覆盖,视觉上就是进度在走。
先算圆周长:2 * π * r。假设 r = 45(半径),那么周长 ≈ 283。把这个值设为 stroke-dasharray 的第一个参数,第二个参数设为 0 —— 这样整圈就是实线;再用 stroke-dashoffset 从 283(完全隐藏)到 0(完全显示)做动画。
常见错误:直接写死 stroke-dasharray: 283,但没配单位或没设 stroke-dashoffset 初始值,导致动画不动或方向反了。
-
stroke-dasharray必须是两个数字,如283, 0,不能只写一个 -
stroke-dashoffset初始值要等于周长,否则起始状态不对 - 动画方向由
stroke-dashoffset从大到小变化决定,别写反
CSS 动画绑定和百分比映射逻辑
纯 CSS 实现动态进度,得靠自定义属性(--progress)驱动 @keyframes,或者更稳妥地用 JS 设置内联 style(因为 CSS 无法把变量直接算进 calc() 里参与 stroke-dashoffset 计算)。
如果坚持纯 CSS,可用 @property(仅 Chromium 110+ 支持),但兼容性差;更通用的做法是让 JS 设置 style="--progress: 75",CSS 里用 calc(283 - (283 * var(--progress) / 100)) 算偏移量。
- Chrome/Firefox/Safari 对
@property支持不一,生产环境慎用 -
calc()中不能直接写var(--p) * 283 / 100,必须加括号确保运算优先级 - 动画时间函数建议用
ease-out,生硬的linear显得机械
响应式适配和 stroke 颜色分层问题
SVG 宽高设为 100% 后,r 值不会自动缩放,导致在不同尺寸下环形粗细/大小失衡。解决办法是用 viewBox 替代固定宽高,并把 r 设为相对值(如 45),再配合 transform: scale() 或容器 font-size 控制整体大小。
另一个坑是背景环和前景环颜色叠在一起时,描边宽度(stroke-width)会影响视觉粗细。比如背景环设 stroke-width: 8,前景环也设 8,实际看起来会比预期粗一倍(重叠区域加深)。
- 用
viewBox="0 0 100 100"+r="45"是最稳的缩放基础 - 前景环的
stroke必须设stroke-linecap: round,否则两端有方角 - 两层
的cx/cy必须完全一致,否则偏心
IE 不支持怎么办?降级方案怎么写
IE 不支持 stroke-dasharray 动画、@property、甚至部分 calc() 写法。真要兼容 IE11,只能放弃 SVG 方案,改用 CSS transform 旋转遮罩层(伪元素 + clip-path 或双半圆拼接),但精度差、角度计算易出错。
更现实的做法是检测 SVGElement 和 CSS.supports('stroke-dasharray', '1,1'),不支持时 fallback 到纯文本进度(如 “75%”)+ 简单横向条。
- IE11 下
stroke-dashoffset动画无效,CSS 动画会卡住 - 不要试图用
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=...)模拟,性能极差 - 若项目已放弃 IE,可放心用现代 SVG + 自定义属性方案
实际最难的部分不是画圆,而是让不同设备、不同缩放比、不同初始值下,stroke-dashoffset 的计算始终对齐起点 —— 多数 bug 都出在周长取值和 offset 初始值没严格对应。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











