You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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>

原理说明

  1. CSS变量:用--progress控制进度百分比,--thickness控制进度条厚度,渐变颜色也可通过变量动态调整。
  2. 遮罩(mask):
    • linear-gradient(#000, #000) padding-box:保留中心内容区域的透明度,让文本正常显示。
    • conic-gradient(#000 calc(var(--progress)*1%), transparent 0) border-box:只显示指定角度的弧形区域,实现进度动态变化。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 11:13:15