Back to CSS Progress Bars Skill Bars Pure CSS
Share
HTML
<dl class="pb-skill">
  <div class="pb-skill-row">
    <dt>TypeScript</dt>
    <dd>
      <span class="pb-skill-rail">
        <span class="pb-skill-fill" style="--pb-skill-w: 92%"></span>
      </span>
      <span class="pb-skill-pct">92%</span>
    </dd>
  </div>
  <div class="pb-skill-row">
    <dt>React</dt>
    <dd>
      <span class="pb-skill-rail">
        <span class="pb-skill-fill" style="--pb-skill-w: 88%; --pb-skill-delay: 0.1s"></span>
      </span>
      <span class="pb-skill-pct">88%</span>
    </dd>
  </div>
  <div class="pb-skill-row">
    <dt>CSS &amp; Sass</dt>
    <dd>
      <span class="pb-skill-rail">
        <span class="pb-skill-fill" style="--pb-skill-w: 95%; --pb-skill-delay: 0.2s"></span>
      </span>
      <span class="pb-skill-pct">95%</span>
    </dd>
  </div>
  <div class="pb-skill-row">
    <dt>Figma</dt>
    <dd>
      <span class="pb-skill-rail">
        <span class="pb-skill-fill" style="--pb-skill-w: 78%; --pb-skill-delay: 0.3s"></span>
      </span>
      <span class="pb-skill-pct">78%</span>
    </dd>
  </div>
</dl>
CSS
.pb-skill {
  width: 260px;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
  font-family: system-ui, sans-serif;
}

.pb-skill-row {
  display: grid;
  grid-template-columns: 90px 1fr;
  align-items: center;
  gap: 10px;
}

.pb-skill dt {
  font-size: 11.5px;
  font-weight: 600;
  color: #fef3c7;
  letter-spacing: 0.02em;
}

.pb-skill dd {
  margin: 0;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 8px;
}

.pb-skill-rail {
  display: block;
  height: 6px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 99px;
  overflow: hidden;
}

.pb-skill-fill {
  display: block;
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, #f97316, #fbbf24);
  border-radius: inherit;
  animation: pbSkillSlide 1s cubic-bezier(0.5, 0, 0.3, 1.2) var(--pb-skill-delay, 0s) forwards;
}

.pb-skill-pct {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  font-weight: 700;
  color: #fbbf24;
  font-variant-numeric: tabular-nums;
  min-width: 30px;
  text-align: right;
}

@media (prefers-reduced-motion: reduce) {
  .pb-skill-fill {
    animation: none;
    width: var(--pb-skill-w, 0%);
  }
}

@keyframes pbSkillSlide {
  to { width: var(--pb-skill-w, 0%); }
}