svg圆弧进度条最可控,用path+stroke-dasharray/dashoffset精确控制绘制长度,配合rotate(-90deg)对齐起点,需通过gettotallength()获取精准周长,避免硬编码导致收口不严。

用 <svg></svg> + <path></path> 画圆弧进度条最可控
纯 CSS 实现圆弧进度条(比如用 border-radius 或伪元素旋转)本质是“骗视觉”,角度不准、动画卡顿、无法动态更新。真正靠谱的方案是 SVG:路径可精确计算,stroke-dasharray 和 stroke-dashoffset 控制绘制长度,配合 JS 轻松绑定数据。
关键不是“怎么画圆”,而是“怎么让圆弧从 0% 渐进到 100%”。核心思路是:
- 先画一个完整圆的
<path></path>,stroke-dasharray设为周长(如251.2),stroke-dashoffset初始也为该值 → 看不见 - 进度为
p(0–1)时,stroke-dashoffset = 周长 × (1 − p)→ 圆弧逐步显现 - 用
transform: rotate(-90deg)把起点调到顶部(默认在 3 点钟方向)
示例(r=40 的圆,中心在 (50,50)):
<svg width="100" height="100"><circle cx="50" cy="50" r="40" fill="none" stroke="#eee" stroke-width="8"></circle><path d="M 50 10 A 40 40 0 0 1 90 50 A 40 40 0 0 1 50 90 A 40 40 0 0 1 10 50 A 40 40 0 0 1 50 10" fill="none" stroke="#4a9eff" stroke-width="8" stroke-dasharray="251.2" stroke-dashoffset="251.2" transform="rotate(-90 50 50)"></path></svg>
stroke-dasharray 和 stroke-dashoffset 容易算错周长
圆周长 = 2 × π × r,但 SVG 中的 <path></path> 若用 A 指令画整圈,实际路径长度可能因精度或实现差异略偏。硬写 2 * Math.PI * r 在某些浏览器里会露白边或收口不严。
更稳妥的做法:
- 用
<circle></circle>元素本身取getTotalLength()(需挂载后):document.querySelector('circle').getTotalLength() - 或直接用
<path></path>的getTotalLength(),但必须确保 DOM 已就绪(比如放DOMContentLoaded里) - 别用近似值如
251或251.3—— 小数点后一位都可能让 100% 时末端不闭合
常见错误现象:stroke-dashoffset 设为 0 时,圆弧看起来“缺一小段”或“多画了一点”——基本就是周长值不准。
用 CSS 动画驱动 stroke-dashoffset 有兼容性陷阱
想用 @keyframes 动画进度?可以,但注意:
- IE 不支持
stroke-dashoffset的 CSS 动画(包括 Edge 17 及更早) - 即使现代浏览器,直接对
<path></path>写animation: progress 2s ease-in-out可能跳帧,尤其低性能设备 - 更稳的方式是用
requestAnimationFrame+ JS 更新style.strokeDashoffset,或用gsap/anime.js等库处理缓动
如果坚持用 CSS 动画,务必加前缀并 fallback:
path {
transition: stroke-dashoffset 0.4s ease-out;
}
.path--active {
stroke-dashoffset: 0 !important;
}
然后 JS 控制 class 切换,比纯 keyframes 更可靠。
响应式下 r 和 stroke-width 不能写死
把 SVG 嵌在自适应容器里时,固定 r="40" 和 stroke-width="8" 会导致小屏上进度条糊成一团,大屏上又太细。
解决方法只有两个:
- 用
viewBox替代固定width/height:<svg viewbox="0 0 100 100"></svg>,然后所有坐标、半径按百分比逻辑设计(r=40 表示占 viewBox 宽高的 40%) -
stroke-width改用单位less 值(如stroke-width="8"),它会随 SVG 缩放自动缩放;若需绝对粗细,得用 JS 监听容器尺寸重设
别试图用 % 单位设 r 或 stroke-width —— SVG 不认这个。
真正难的不是画出圆弧,而是让不同尺寸、不同进度、不同动画节奏下的圆弧始终对齐起点、闭合终点、不锯齿、不跳变。这些细节全藏在 viewBox、getTotalLength() 和 transform 的组合里,少调一个参数就可能白忙半小时。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











