Skip to content

Circular Percent

A copy-paste progress component in pure HTML & CSS. Zero dependencies, framework-agnostic, MIT-licensed.

ProgressHTMLCSSany framework
75%

Copy into your project

HTML
<!-- Circular Percent Progress
     stroke-dashoffset target = circumference - (circumference * percent/100)
     r=24 → circumference ≈ 150.8; 75% → 150.8 - 113.1 ≈ 37.7 -->
<div class="nuda-circular-percent" role="progressbar"
     aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"
     aria-label="75% complete">
  <svg viewBox="0 0 60 60" width="56" height="56">
    <circle class="nuda-circular-percent__track"
      cx="30" cy="30" r="24" fill="none" stroke-width="5" />
    <circle class="nuda-circular-percent__fill"
      cx="30" cy="30" r="24" fill="none" stroke-width="5"
      stroke-linecap="round"
      stroke-dasharray="150.8"
      stroke-dashoffset="37.7" />
  </svg>
  <span class="nuda-circular-percent__label">75%</span>
</div>
CSS
/* Circular Percent Progress
   SVG ring that animates its fill via stroke-dashoffset on load.
   Customize: --circpct-color, --circpct-track */

.nuda-circular-percent {
  --circpct-color: #e4ff54;
  --circpct-track: rgba(255, 255, 255, 0.1);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.nuda-circular-percent__track {
  stroke: var(--circpct-track);
}

.nuda-circular-percent__fill {
  stroke: var(--circpct-color);
  transform: rotate(-90deg);
  transform-origin: center;
  stroke-dasharray: 150.8;
  animation: nuda-circular-percent 1.6s ease-out forwards;
}

.nuda-circular-percent__label {
  position: absolute;
  font-size: 13px;
  font-weight: 600;
  color: #fafafa;
  font-family: system-ui, sans-serif;
}

@keyframes nuda-circular-percent {
  from { stroke-dashoffset: 150.8; }
  to   { stroke-dashoffset: 37.7; }
}

@media (prefers-reduced-motion: reduce) {
  .nuda-circular-percent__fill { animation: none; stroke-dashoffset: 37.7; }
}

How to use Circular Percent

Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.

Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.

More progress components

← Browse all NudaUI components