结论:别用 conic-gradient 做跨端圆环进度条,微信小程序不解析该函数;唯一稳方案是 SVG + stroke-dasharray 配合固定 viewBox 与 JS 动态算周长,小程序端需用 canvas 绘制或双半圆 clip-path 方案,且所有动画必须包裹 requestAnimationFrame 并检测页面可见性。

直接结论:别用 conic-gradient 做跨端圆环进度条,微信小程序里它根本不会渲染;真要兼容 iOS/Android/小程序三端,唯一稳的方案是 SVG + stroke-dasharray 配合 JS 动态算周长,且必须固定 viewBox。
为什么 conic-gradient 在移动端实际不可用
很多人在 H5 上写 background: conic-gradient(...) 效果很顺,一上真机或编译进 uni-app 小程序就白屏。这不是兼容性问题,是底层引擎不识别该函数名——微信小程序基础库(截至 2026.4)压根不解析 conic-gradient,CSS 规则被静默丢弃,控制台零报错。常见现象包括:
- 开发工具预览正常,iOS/Android 真机调试时进度环空白
- 用
getComputedStyle(el).background查值,返回空字符串 - 第三方 UI 库(如 uView 的
u-circle-progress)若未做平台判断,内部用了conic-gradient,在小程序里直接失效
SVG + stroke-dasharray 的正确写法
这个方案在 Web、App、小程序(通过 Canvas 或原生 SVG 组件)都可落地,关键是不能让周长计算依赖屏幕像素。错误做法是写死 r="45" 再靠 width: 100% 拉伸,这会导致描边糊、动画卡。正确路径是:
- 固定
viewBox="0 0 200 200",逻辑画布尺寸统一 -
——r占 viewBox 宽高的 45%,缩放时比例不变 - 周长按
2 * Math.PI * 90 ≈ 565.5计算,设为stroke-dasharray="565.5 0" - JS 更新进度时,只改
stroke-dashoffset:偏移量 =565.5 * (1 - progress)(progress是 0~1 小数) - 避免过渡倒流:首次设置时先清空
stroke-dashoffset,再设新值,否则 Safari 会反向动画
uni-app 小程序端必须绕开的坑
小程序的 组件不支持动态绑定 stroke-dasharray 或内联样式更新,硬写 :style="{ strokeDasharray: ... }" 无效。可行路径只有两个:
- 用
绘制:调用uni.createCanvasContext(canvasId),用arc()+stroke()手动画弧,起始角必须显式设为-Math.PI / 2(对应 12 点钟方向),否则进度偏移 90° - 退回到纯 CSS 双半圆方案:
.circle-left和.circle-right各控 0–50% / 50–100%,靠clip-path截取 +transform: rotate()暴露弧段,但需手动处理旋转角度与百分比换算 - 禁用
will-change: transform:小程序 WebView 不支持该属性,加了反而更卡
适配不同屏幕的关键单位选择
高度和线宽不能用 px 或 rem:
-
px在 iPhone SE(320px 宽)和 iPad(1024px 宽)上视觉粗细差异极大 -
rem会被用户字体缩放干扰,导致进度环变粗、消失甚至错位 - 统一用
vh:例如height: 0.15vh(≈1.5px @375px 宽屏),iOS/Android 兼容性好 - 如果用了 CSS 变量如
--ring-width,JS 更新时必须同步调用el.style.setProperty('--ring-width', '0.15vh'),否则动画断掉
最易被忽略的一点:所有动态更新(无论是 stroke-dashoffset 还是 transform: rotate())都必须包裹在 requestAnimationFrame 中,且需检测 document.hidden —— 页面切后台时暂停更新,否则低端安卓机会持续占用 JS 线程,导致返回前台后进度条“突变”而非平滑流动。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











