如何用HTML/CSS实现带中心数字的渐变进度指示器?
需求:带渐变填充的动态进度指示器(中心显示数字)
我想用HTML/CSS创建一个带渐变填充的进度指示器,类似下图,中心显示数字:
我已经实现了两种效果:
- 单色半圆进度条
- 带渐变的整圆进度条
以下是现有代码:
body { background: linear-gradient(90deg, #c084fc22 0%, #fb923c22 100%); display: flex; gap: 10px; } .progress { width: 100px; height: 100px; display: flex; align-items: center; justify-content: center; box-sizing: border-box; font-size: 30px; } .progress--half { border-radius: 50%; border: solid 10px #fb923c; mask: linear-gradient(#000, #000) padding-box, conic-gradient(#000 50%, #ffffff22 0%) border-box; } .progress--gradient { position: relative } .progress--gradient::before { content: ""; position: absolute; z-index: -1; inset: 0; padding: 10px; border-radius: 50%; background: conic-gradient(#fb923c, #c084fc, #818cf8, #c084fc, #fb923c); mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); mask-composite: exclude; } .progress--half-gradient { /* ? */ }
<div class="progress progress--half">50%</div> <div class="progress progress--gradient">50%</div>
我的目标是结合这两种方法,但无法适配出支持完全动态数值的渐变弧形进度条(怀疑之前的方案只支持25%/50%这类固定值),同时要求图表背景透明。请问能否完全用CSS实现该效果,还是需要考虑SVG或其他方案?
方案一:纯CSS实现动态渐变弧形进度条
可以通过结合conic-gradient、mask和CSS变量实现完全动态的效果,核心思路是用遮罩控制显示的弧形范围,同时给渐变进度绑定自定义变量。
修改后的代码如下:
body { background: linear-gradient(90deg, #c084fc22 0%, #fb923c22 100%); display: flex; gap: 20px; align-items: center; justify-content: center; min-height: 100vh; margin: 0; } .progress { width: 100px; height: 100px; display: flex; align-items: center; justify-content: center; box-sizing: border-box; font-size: 30px; position: relative; } /* 动态渐变弧形进度条核心样式 */ .progress--dynamic-gradient { --progress: 75; /* 进度值,0-100 */ --thickness: 10px; /* 进度条厚度 */ --gradient-start: #fb923c; --gradient-middle: #c084fc; --gradient-end: #818cf8; border-radius: 50%; /* 遮罩:保留中心内容区域 + 显示指定角度的弧形边框 */ mask: linear-gradient(#000, #000) padding-box, conic-gradient(#000 calc(var(--progress) * 1%), transparent 0) border-box; /* 渐变背景作为进度条 */ background: conic-gradient(from 0deg, var(--gradient-start), var(--gradient-middle), var(--gradient-end)); /* 用padding模拟边框厚度,保证中心内容区域大小 */ padding: var(--thickness); overflow: hidden; } /* 中心文本容器,覆盖在进度条上 */ .progress--dynamic-gradient .progress__label { position: absolute; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: transparent; z-index: 1; }
<div class="progress progress--dynamic-gradient" style="--progress: 30"> <span class="progress__label">30%</span> </div> <div class="progress progress--dynamic-gradient" style="--progress: 75"> <span class="progress__label">75%</span> </div> <div class="progress progress--dynamic-gradient" style="--progress: 100"> <span class="progress__label">100%</span> </div>
原理说明
- CSS变量:用
--progress控制进度百分比,--thickness控制进度条厚度,渐变颜色也可通过变量动态调整。 - 遮罩(mask):
linear-gradient(#000, #000) padding-box:保留中心内容区域的透明度,让文本正常显示。conic-gradient(#000 calc(var(--progress)*1%), transparent 0) border-box:只显示指定角度的弧形区域,实现进度动态变化。
- padding模拟厚度:通过padding把背景限制在“边框”区域,配合
border-box遮罩,实现弧形进度条视觉效果,同时背景完全透明。
方案二:SVG实现(更灵活的复杂场景)
如果需要更精细的控制(比如渐变方向、弧形起点角度,或兼容老浏览器),SVG是更可靠的选择,天生支持透明背景和动态数值。
示例代码:
<svg class="progress-svg" width="100" height="100" viewBox="0 0 100 100"> <!-- 背景弧形(可选,显示未填充部分) --> <circle cx="50" cy="50" r="40" fill="none" stroke="#eee" stroke-width="10" /> <!-- 渐变填充弧形 --> <defs> <linearGradient id="progressGradient" x1="0%" y1="0%" x2="100%" y2="0%"> <stop offset="0%" stop-color="#fb923c" /> <stop offset="50%" stop-color="#c084fc" /> <stop offset="100%" stop-color="#818cf8" /> </linearGradient> </defs> <circle cx="50" cy="50" r="40" fill="none" stroke="url(#progressGradient)" stroke-width="10" stroke-dasharray="251.2" stroke-dashoffset="62.8" stroke-linecap="round" transform="rotate(-90 50 50)" /> <!-- 中心文本 --> <text x="50" y="55" text-anchor="middle" font-size="20" fill="#333">75%</text> </svg>
.progress-svg { background: transparent; }
动态控制说明
stroke-dasharray:值为圆的周长(2*π*r,这里r=40,周长≈251.2)。stroke-dashoffset:计算方式为周长*(1- 进度/100),比如75%进度的offset是251.2*(1-0.75)=62.8。- 可通过JavaScript动态修改
stroke-dashoffset和文本内容,实现实时更新。
方案对比
- 纯CSS:代码简洁,无需额外标签,适合简单动态进度场景,现代浏览器支持良好。
- SVG:兼容性更好,支持更多自定义效果(比如圆角端点、渐变方向调整),适合复杂交互或需兼容旧浏览器的场景。
内容的提问来源于stack exchange,提问作者femtozer
相关产品推荐
相关产品推荐

