{ CF }

30 CSS Badges

Core Web Vitals

LCP, INP, CLS — the three real-world page-experience signals Google ranks on. Three SVG arcs draw to their verdict on load. Green / amber / red thresholds match Google's field-data classification.

Pure CSS MIT licensed

Core Web Vitals the 12th of 30 designs in the 30 CSS Badges collection. The design is implemented in pure CSS — no JavaScript required. Copy the HTML and CSS panels below into your project. Because the demo is pure CSS, it works in any framework or templating engine you happen to use. The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.

Live preview

Open in playground

The code

<div class="cwv-stage">
  <div class="cwv-card">
    <div class="cwv-header">
      <div class="cwv-title">Core Web Vitals · Field Data</div>
      <div class="cwv-pass-count">2 / 3 Pass</div>
    </div>
    <div class="cwv-gauges">
      <div class="cwv-gauge">
        <svg viewBox="0 0 90 90" aria-hidden="true">
          <circle class="cwv-gauge-track" cx="45" cy="45" r="36"/>
          <circle class="cwv-gauge-arc" cx="45" cy="45" r="36" stroke="#ffa400" data-len="140" transform="rotate(-90 45 45)"/>
          <text x="45" y="43" text-anchor="middle" class="cwv-gauge-val">2.9s</text>
          <text x="45" y="57" text-anchor="middle" class="cwv-gauge-unit">LCP</text>
        </svg>
        <div class="cwv-metric-name">LCP</div>
        <div class="cwv-metric-verdict cwv-verdict-needs">Needs Work</div>
      </div>
      <div class="cwv-gauge">
        <svg viewBox="0 0 90 90" aria-hidden="true">
          <circle class="cwv-gauge-track" cx="45" cy="45" r="36"/>
          <circle class="cwv-gauge-arc" cx="45" cy="45" r="36" stroke="#0cce6b" data-len="205" transform="rotate(-90 45 45)"/>
          <text x="45" y="43" text-anchor="middle" class="cwv-gauge-val">89ms</text>
          <text x="45" y="57" text-anchor="middle" class="cwv-gauge-unit">INP</text>
        </svg>
        <div class="cwv-metric-name">INP</div>
        <div class="cwv-metric-verdict cwv-verdict-good">Good</div>
      </div>
      <div class="cwv-gauge">
        <svg viewBox="0 0 90 90" aria-hidden="true">
          <circle class="cwv-gauge-track" cx="45" cy="45" r="36"/>
          <circle class="cwv-gauge-arc" cx="45" cy="45" r="36" stroke="#0cce6b" data-len="193" transform="rotate(-90 45 45)"/>
          <text x="45" y="43" text-anchor="middle" class="cwv-gauge-val">0.08</text>
          <text x="45" y="57" text-anchor="middle" class="cwv-gauge-unit">CLS</text>
        </svg>
        <div class="cwv-metric-name">CLS</div>
        <div class="cwv-metric-verdict cwv-verdict-good">Good</div>
      </div>
    </div>
    <div class="cwv-footer">
      <div class="cwv-origin">example.com/blog/seo-guide/</div>
      <div class="cwv-date">28-day field data</div>
    </div>
  </div>
</div>
.cwv-stage {
  background: #0d1117;
  padding: 50px 40px;
  display: flex;
  flex-direction: column;
  gap: 28px;
  align-items: center;
  justify-content: center;
  min-height: 420px;
}
.cwv-card {
  background: #161b22;
  border: 1px solid #30363d;
  border-radius: 8px;
  padding: 28px 32px 24px;
  width: 100%;
  max-width: 480px;
}
.cwv-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 24px;
}
.cwv-title {
  font-family: system-ui, "Bricolage Grotesque", sans-serif;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #8b949e;
}
.cwv-pass-count {
  font-family: ui-monospace, "JetBrains Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.1em;
  color: #0cce6b;
  padding: 3px 10px;
  border: 1px solid rgba(12, 206, 107, 0.3);
  border-radius: 20px;
}
.cwv-gauges {
  display: flex;
  gap: 24px;
  justify-content: center;
  align-items: flex-end;
  padding-bottom: 20px;
  border-bottom: 1px solid #21262d;
}
.cwv-gauge {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.cwv-gauge svg {
  width: 96px;
  height: 96px;
  overflow: visible;
}
.cwv-gauge-track {
  fill: none;
  stroke: #21262d;
  stroke-width: 7;
  stroke-linecap: round;
}
.cwv-gauge-arc {
  fill: none;
  stroke-width: 7;
  stroke-linecap: round;
  stroke-dasharray: 226;
  stroke-dashoffset: 226;
  animation: cwv-draw 1.1s cubic-bezier(0.4, 0, 0.2, 1) 0.3s forwards;
}
@keyframes cwv-draw {
  to { stroke-dashoffset: var(--cwv-target, 86); }
}
@media (prefers-reduced-motion: reduce) {
  .cwv-gauge-arc { animation: none; stroke-dashoffset: 86; }
}
.cwv-gauge-val {
  font-family: ui-monospace, "JetBrains Mono", monospace;
  fill: #e6edf3;
  font-size: 14px;
  font-weight: 700;
}
.cwv-gauge-unit {
  font-family: system-ui, "Bricolage Grotesque", sans-serif;
  fill: #8b949e;
  font-size: 10px;
}
.cwv-metric-name {
  font-family: ui-monospace, "JetBrains Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.14em;
  color: #8b949e;
  text-transform: uppercase;
}
.cwv-metric-verdict {
  font-family: system-ui, "Bricolage Grotesque", sans-serif;
  font-size: 9px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin-top: -2px;
}
.cwv-verdict-good  { color: #0cce6b; }
.cwv-verdict-needs { color: #ffa400; }
.cwv-verdict-poor  { color: #ff4e42; }
.cwv-footer {
  margin-top: 18px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.cwv-origin {
  font-family: ui-monospace, "JetBrains Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.06em;
  color: #4a90d9;
}
.cwv-date {
  font-family: system-ui, "Bricolage Grotesque", sans-serif;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: #8b949e;
  text-transform: uppercase;
}

Search CodeFronts

Loading…