conic-gradient在微信小程序中不可用,因底层渲染引擎不支持;stroke-dasharray可用但受限于Canvas;稳定跨端方案是CSS旋转双半圆+clip-path。

直接说结论:在微信小程序(含 Uni-app 编译为小程序)中,conic-gradient 不可用,stroke-dasharray 可用但需绕开 Canvas 限制;真正稳定、跨端、可动画的方案仍是 CSS 旋转双半圆 + clip。
为什么 conic-gradient 在微信小程序里根本不能用
微信小程序基础库(截至 2026.4)的 web-view 和 canvas 外部视图层,底层渲染引擎不支持 conic-gradient。哪怕你在 uni-app 的 H5 端写得再漂亮,一编译到微信小程序,CSS 会静默失效,控制台无报错,但进度条直接空白或显示为纯色块。这不是兼容性问题,是原生不识别该函数名——连 background: conic-gradient(...) 都会被忽略。
常见错误现象:
• 开发工具预览正常,真机调试白屏
• 进度变化时无动画,只有突变
• 使用 uni.createSelectorQuery() 查 DOM 样式,发现 background 值为空字符串
- 替代思路:放弃
conic-gradient,改用linear-gradient拼接 +transform: rotate模拟锥形渐变效果(仅限 H5/App) - 小程序端必须换路:回到双半圆结构,靠
rotate控制可见弧段 - 注意:某些第三方 UI 库(如 uView、uni-ui)的
circle-progress组件若未做平台判断,内部用了conic-gradient,就会在小程序上挂掉
stroke-dasharray 能用,但 Canvas 是拦路虎
在纯 Web 环境下,stroke-dasharray 配合 <svg><circle> 是最简洁的圆环实现方式。但在微信小程序中,你无法直接操作 SVG 元素的 style 或 setAttribute 动态更新 stroke-dasharray —— 小程序的 svg 组件是只读的,且不支持绑定内联样式。
立即学习“前端免费学习笔记(深入)”;
如果你硬要用 SVG,唯一可行路径是:
• 用 uni.createCanvasContext 绘制 SVG 效果(本质还是 Canvas)
• 或者用 canvas 组件 + arc + stroke 手动画弧
- Canvas 方案性能差:每帧重绘,iOS 还好,低端安卓机容易掉帧
- 动画卡顿:
requestAnimationFrame在小程序里受平台节流,setTimeout模拟又不准 - 百分比计算易出错:起始角默认是
-Math.PI / 2(12 点钟方向),但很多教程漏写这行,导致进度偏移 90°
CSS 双半圆方案的关键参数与坑点
这个方案依赖两组嵌套:.circle-left 和 .circle-right 各自控制 0–50% 和 50–100%,核心是 clip: rect(0, Xpx, Ypx, 0) 截取可见区域 + transform: rotate() 暴露进度。
关键参数差异:
• 左半区父容器宽 = 直径 / 2,overflow: hidden
• 内层圆直径 = 直径,border-radius: 50%,clip: rect(0, 直径/2, 直径, 0)(只留左半)
• 右半区同理,但 clip 改为 rect(0, 直径, 直径, 直径/2)(只留右半)
- 安卓衔接卡顿:50% 切换瞬间左右半圆旋转角度不连续,需加
transition: transform 0.2s ease-out,且右半圆初始rotate设为180deg而非0 - 微信小程序里
clip属性已被废弃,必须用clip-path: inset(0 50% 0 0)替代(但部分旧基础库不支持,保险起见仍用clip+ 条件编译) - 不要用
%单位写clip值,小程序不认,必须用px
真正该关注的细节不是怎么画,而是怎么“动”
所有方案里,动画平滑度取决于两点:是否启用硬件加速、是否避免 layout 触发。CSS transform 和 opacity 是唯二能进 GPU 合成层的属性。所以:
• 绝对不要在动画中修改 width、height、left、top
• clip 和 clip-path 都会触发 layout,只能用于初始截取,动态变化必须靠 rotate
最容易被忽略的一点:微信小程序的 setData 频率上限是 10Hz,如果你用 v-model 或 watch 实时监听 percent 并频繁触发 setData,动画必然卡顿。正确做法是用 requestAnimationFrame 聚合变更,或改用 this.$nextTick + 节流。


















