移动端环形进度条必须用SVG+stroke-dasharray,conic-gradient在iOS Safari(尤其15.2及更早)静默降级为纯色或空白;SVG在所有主流移动端浏览器中行为稳定、可精确控制,核心是真机不崩。

移动端环形进度条必须用 SVG + stroke-dasharray,别碰 conic-gradient
iOS Safari(尤其是 iOS 15.2 及更早)对 conic-gradient 支持极差,静默降级为纯色或空白,且无法 fallback 成可用形态。而 SVG 的 <circle></circle> 在所有主流移动端浏览器(包括 Android WebView、iOS Safari 12+)中行为稳定、可精确控制。核心不是“选哪种炫技方案”,而是“哪一种在真机上不崩”。
实操要点:
- 用
<svg viewBox="0 0 100 100">定义坐标系,避免用width/height硬设尺寸——否则缩放时r值失效,周长计算错 -
<circle r="45" cx="50" cy="50">中的r必须是数值(无单位),viewBox决定缩放基准 - 周长必须预计算:例如
r=45→2 * Math.PI * 45 ≈ 282.74→ 四舍五入取283,写死在stroke-dasharray="283,283",CSS 里不能用calc()动态算 - 起始点必须校正:加
transform="rotate(-90 50 50)",把 0% 对齐顶部(12 点钟方向),否则进度从右侧开始,用户直觉错乱
如何让 SVG 环形进度条在不同屏幕密度下粗细一致?
固定 stroke-width(如 5px)在 iPhone SE 上看起来像线,在 iPad 上又太粗。真正可靠的方案是用 CSS 自定义属性 + 视口单位动态绑定,但只作用于 stroke-width,不碰 r。
做法:
立即学习“前端免费学习笔记(深入)”;
- SVG 外层容器设
width: 100%; aspect-ratio: 1;,保证正圆不拉伸 - 给
<circle>设置stroke-width: calc(0.15vh + 0.05vmin);——vmin防止窄屏下线过细,vh控制高度方向基准 - JS 更新进度时,只改
style.strokeDashoffset,不要重写整个stroke-dasharray,避免触发重排 - 务必加
will-change: transform;到<circle>上(仅在动画期间),iOS Safari 对stroke-dashoffset动画首帧掉帧严重,加了能稳住 60fps
进度从 0% 到 100% 动画卡顿?检查这三处
移动端卡顿几乎都来自三个地方:布局抖动、合成层未启用、起始偏移值错误。不是动画本身慢,而是浏览器没走 GPU 路径。
排查清单:
- 别在
<circle>上写transition: stroke-dashoffset 0.3s ease—— 初始渲染时会从0突跳到目标值,造成闪动;正确写法是transition: stroke-dashoffset 0.3s linear,且 JS 设置初始值时直接设为最大偏移(如283) - 确保
stroke-dashoffset是整数,不要传小数(如282.743),某些安卓 WebView 渲染异常 - 动画过程中如果同时触发布局(比如父容器
font-size变化、margin动画),stroke-dashoffset会被强制降级到 CPU 渲染——把它和其它动画拆开,单独挂一个 class 控制
指示数字居中但跟着旋转?这是定位层级错了
指示器(如 75%)必须完全脱离 SVG 的变换流。常见错误是把它塞进 <svg> 里,再用 transform: rotate(90deg) 挡回去——精度误差累积,小屏上偏移明显。
正确结构:
-
<div class="progress-wrapper">包裹整个 SVG 和文字 -
<svg>单独占位,不设position -
<div class="progress-text">75%</div>绝对定位在 wrapper 内部:position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); - 不要给
.progress-text加任何transform: rotate(),它天生就该静止
最易被忽略的是:SVG 容器若用了 transform: scale(0.8) 或其他缩放,wrapper 的 top: 50% 仍按原始尺寸计算,导致文字偏移。解决办法是让 wrapper 的宽高严格等于 SVG 的 viewBox 尺寸(如 100px × 100px),再用 aspect-ratio 控制响应式缩放。


















