产品要一个 72% 的环形进度,设计稿标了直径 120px、线宽 10px、圆头端点。第一反应是去翻 SVG,其实纯 CSS 一行就够了。
写法一:conic-gradient 加遮罩
核心是把整圆切成扇形,中间挖个洞:
.ring { width: 120px; height: 120px; border-radius: 50%; background: conic-gradient(#2563eb 0 72%, #e5e7eb 0); mask: radial-gradient(circle, transparent 50px, #000 51px); }50px 是内半径,51px 多留 1px 给抗锯齿,不加边缘会有毛刺。72% 换成变量,用 CSS 自定义属性或者内联样式驱动,改数字就能动。
好处是 DOM 只有一层,坏处是圆头端点做不出来,渐变描边也难。transition 直接加在 background 上部分浏览器不认,得用 @property 注册一个角度类型才行。
写法二:SVG 的 stroke-dasharray
要圆头、要渐变描边就用 SVG。半径取 54,周长 2πr 约 339.3,虚线和偏移都按这个数算。
<circle r=54 stroke-dasharray=339.3 stroke-dashoffset=95 />72% 对应的 offset 是 339.3 乘以 0.28,约 95。外面套一层 transform: rotate(-90deg),让它从 12 点方向开始跑,不然起点在 3 点。
SVG 的好处是线宽、圆头、渐变都能精确控制,代价是多写几行,动画还得靠 stroke-dashoffset 的过渡。
怎么选
纯色、只要一个进度值,用 conic-gradient,DOM 少一层,改数值最省事。要描边渐变、圆头、加阴影,用 SVG,别硬用 CSS 凑。
两者都在 120px 尺寸下试过,低端安卓机上 conic-gradient 的重绘开销更小一些。中间的百分比数字单独放一层绝对定位,别指望伪元素,字号一改就歪。