Open demo

CSS code

HTML
<div class="sc-grid">
  <article class="sc-card">
    <div class="sc-top"><h2 class="sc-label">Revenue</h2><span class="sc-ic sc-i1" aria-hidden="true">💳</span></div>
    <p class="sc-num">$48,290</p>
    <p class="sc-delta sc-up"><span aria-hidden="true">▲</span><span class="sc-sr">Up</span> 12.4% <span class="sc-vs">vs last month</span></p>
    <div class="sc-spark sc-s1" role="img" aria-label="Last seven months, trending up"><i style="height:35%"></i><i style="height:48%"></i><i style="height:42%"></i><i style="height:60%"></i><i style="height:55%"></i><i style="height:74%"></i><i class="sc-hi" style="height:92%"></i></div>
  </article>
  <article class="sc-card">
    <div class="sc-top"><h2 class="sc-label">Active users</h2><span class="sc-ic sc-i2" aria-hidden="true">👥</span></div>
    <p class="sc-num">18,442</p>
    <p class="sc-delta sc-up"><span aria-hidden="true">▲</span><span class="sc-sr">Up</span> 3.1% <span class="sc-vs">vs last month</span></p>
    <div class="sc-spark sc-s2" role="img" aria-label="Last seven months, trending up"><i style="height:55%"></i><i style="height:58%"></i><i style="height:50%"></i><i style="height:64%"></i><i style="height:61%"></i><i style="height:70%"></i><i class="sc-hi" style="height:76%"></i></div>
  </article>
  <article class="sc-card">
    <div class="sc-top"><h2 class="sc-label">Conversion rate</h2><span class="sc-ic sc-i3" aria-hidden="true">📉</span></div>
    <p class="sc-num">2.8%</p>
    <p class="sc-delta sc-down"><span aria-hidden="true">▼</span><span class="sc-sr">Down</span> 0.4pt <span class="sc-vs">vs last month</span></p>
    <div class="sc-spark sc-s3" role="img" aria-label="Last seven months, trending down"><i style="height:80%"></i><i style="height:72%"></i><i style="height:75%"></i><i style="height:60%"></i><i style="height:52%"></i><i style="height:45%"></i><i class="sc-hi" style="height:38%"></i></div>
  </article>
</div>
CSS
/* KPI cards: label, icon tile, big figure, a delta pill and a bar sparkline drawn with plain elements.
   Each bar's height is an inline percentage; the highlighted last bar takes the card's accent through currentColor. */
.sc-grid,.sc-grid *,.sc-grid *::before,.sc-grid *::after{box-sizing:border-box}
.sc-grid{display:flex;flex-wrap:wrap;justify-content:center;gap:20px}
.sc-card{width:250px;background:#fff;border:1px solid #e9ecf1;border-radius:16px;padding:22px 22px 18px;transition:box-shadow .18s,transform .18s}
.sc-card:hover{transform:translateY(-4px);box-shadow:0 18px 36px -16px rgba(16,24,40,.16)}
.sc-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.sc-label{font-size:.8rem;font-weight:600;color:#667085;margin:0}
.sc-ic{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:1rem}
.sc-i1{background:#eef4ff}.sc-i2{background:#effdf4}.sc-i3{background:#fdf2f8}
.sc-num{font-size:1.75rem;font-weight:800;letter-spacing:-.03em;color:#101828;margin:0}
.sc-delta{display:inline-flex;align-items:center;gap:4px;font-size:.75rem;font-weight:700;padding:3px 9px;border-radius:999px;margin:8px 0 14px}
.sc-up{background:#e8f8ee;color:#15803d}
.sc-down{background:#feecec;color:#b91c1c}
.sc-vs{font-weight:500;color:#5d6679}
.sc-spark{display:flex;align-items:flex-end;gap:4px;height:38px}
.sc-spark i{flex:1;border-radius:3px 3px 0 0;background:#e3e9f2}
.sc-spark i.sc-hi{background:currentColor}
.sc-s1{color:#3b82f6}.sc-s2{color:#16a34a}.sc-s3{color:#db2777}
.sc-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
@media (prefers-reduced-motion:reduce){.sc-card{transition:none}.sc-card:hover{transform:none}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div class="row row-cols-auto justify-content-center g-3">
  <div class="col">
    <article class="card h-100 sc-card">
      <div class="card-body">
        <div class="sc-top d-flex align-items-center justify-content-between"><h2 class="sc-label">Revenue</h2><span class="sc-ic sc-i1 d-flex align-items-center justify-content-center" aria-hidden="true">💳</span></div>
        <p class="sc-num">$48,290</p>
        <p class="badge rounded-pill sc-delta sc-up"><span aria-hidden="true">▲</span><span class="visually-hidden">Up</span> 12.4% <span class="sc-vs">vs last month</span></p>
        <div class="sc-spark sc-s1 d-flex align-items-end" role="img" aria-label="Last seven months, trending up"><i style="height:35%"></i><i style="height:48%"></i><i style="height:42%"></i><i style="height:60%"></i><i style="height:55%"></i><i style="height:74%"></i><i class="sc-hi" style="height:92%"></i></div>
      </div>
    </article>
  </div>
  <div class="col">
    <article class="card h-100 sc-card">
      <div class="card-body">
        <div class="sc-top d-flex align-items-center justify-content-between"><h2 class="sc-label">Active users</h2><span class="sc-ic sc-i2 d-flex align-items-center justify-content-center" aria-hidden="true">👥</span></div>
        <p class="sc-num">18,442</p>
        <p class="badge rounded-pill sc-delta sc-up"><span aria-hidden="true">▲</span><span class="visually-hidden">Up</span> 3.1% <span class="sc-vs">vs last month</span></p>
        <div class="sc-spark sc-s2 d-flex align-items-end" role="img" aria-label="Last seven months, trending up"><i style="height:55%"></i><i style="height:58%"></i><i style="height:50%"></i><i style="height:64%"></i><i style="height:61%"></i><i style="height:70%"></i><i class="sc-hi" style="height:76%"></i></div>
      </div>
    </article>
  </div>
  <div class="col">
    <article class="card h-100 sc-card">
      <div class="card-body">
        <div class="sc-top d-flex align-items-center justify-content-between"><h2 class="sc-label">Conversion rate</h2><span class="sc-ic sc-i3 d-flex align-items-center justify-content-center" aria-hidden="true">📉</span></div>
        <p class="sc-num">2.8%</p>
        <p class="badge rounded-pill sc-delta sc-down"><span aria-hidden="true">▼</span><span class="visually-hidden">Down</span> 0.4pt <span class="sc-vs">vs last month</span></p>
        <div class="sc-spark sc-s3 d-flex align-items-end" role="img" aria-label="Last seven months, trending down"><i style="height:80%"></i><i style="height:72%"></i><i style="height:75%"></i><i style="height:60%"></i><i style="height:52%"></i><i style="height:45%"></i><i class="sc-hi" style="height:38%"></i></div>
      </div>
    </article>
  </div>
</div>
CSS
/* Bootstrap .card + .badge in a .row-cols-auto grid; the sparkline is flex utilities plus inline bar heights.
   The highlighted last bar takes the card's accent through currentColor. */
.sc-card{--bs-card-border-color:#e9ecf1;--bs-card-border-radius:16px;--bs-card-spacer-x:22px;--bs-card-spacer-y:22px;width:250px;transition:box-shadow .18s,transform .18s}
.sc-card .card-body{padding-bottom:18px}
.sc-card:hover{transform:translateY(-4px);box-shadow:0 18px 36px -16px rgba(16,24,40,.16)}
.sc-top{margin-bottom:14px}
.sc-label{font-size:.8rem;font-weight:600;line-height:normal;color:#667085;margin:0}
.sc-ic{width:36px;height:36px;border-radius:10px;font-size:1rem}
.sc-i1{background:#eef4ff}.sc-i2{background:#effdf4}.sc-i3{background:#fdf2f8}
.sc-num{font-size:1.75rem;font-weight:800;letter-spacing:-.03em;color:#101828;margin:0}
.sc-delta{--bs-badge-font-size:.75rem;--bs-badge-font-weight:700;--bs-badge-padding-x:9px;--bs-badge-padding-y:3px;display:inline-flex;align-items:center;gap:4px;margin:8px 0 14px}
.sc-up{background:#e8f8ee;--bs-badge-color:#15803d}
.sc-down{background:#feecec;--bs-badge-color:#b91c1c}
.sc-vs{font-weight:500;color:#5d6679}
.sc-spark{gap:4px;height:38px}
.sc-spark i{flex:1;border-radius:3px 3px 0 0;background:#e3e9f2}
.sc-spark i.sc-hi{background:currentColor}
.sc-s1{color:#3b82f6}.sc-s2{color:#16a34a}.sc-s3{color:#db2777}
@media (prefers-reduced-motion:reduce){.sc-card{transition:none}.sc-card:hover{transform:none}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div class="flex flex-wrap justify-center gap-5">
  <article class="w-[250px] rounded-2xl border border-[#e9ecf1] bg-white px-[22px] pt-[22px] pb-[18px] transition-[translate,box-shadow] duration-[180ms] hover:-translate-y-1 hover:shadow-[0_18px_36px_-16px_rgba(16,24,40,.16)] motion-reduce:transition-none motion-reduce:hover:translate-y-0">
    <div class="mb-3.5 flex items-center justify-between"><h2 class="text-[.8rem] font-semibold text-[#667085]">Revenue</h2><span aria-hidden="true" class="flex size-9 items-center justify-center rounded-[10px] bg-[#eef4ff] text-base">💳</span></div>
    <p class="text-[1.75rem] font-extrabold tracking-[-.03em] text-[#101828]">$48,290</p>
    <p class="mt-2 mb-3.5 inline-flex items-center gap-1 rounded-full bg-[#e8f8ee] px-[9px] py-[3px] text-[.75rem] font-bold text-[#15803d]"><span aria-hidden="true">▲</span><span class="sr-only">Up</span> 12.4% <span class="font-medium text-[#5d6679]">vs last month</span></p>
    <div role="img" aria-label="Last seven months, trending up" class="flex h-[38px] items-end gap-1 [&>i]:flex-1 [&>i]:rounded-t-[3px] [&>i]:bg-[#e3e9f2]"><i class="h-[35%]"></i><i class="h-[48%]"></i><i class="h-[42%]"></i><i class="h-[60%]"></i><i class="h-[55%]"></i><i class="h-[74%]"></i><i class="h-[92%] bg-[#3b82f6]!"></i></div>
  </article>
  <article class="w-[250px] rounded-2xl border border-[#e9ecf1] bg-white px-[22px] pt-[22px] pb-[18px] transition-[translate,box-shadow] duration-[180ms] hover:-translate-y-1 hover:shadow-[0_18px_36px_-16px_rgba(16,24,40,.16)] motion-reduce:transition-none motion-reduce:hover:translate-y-0">
    <div class="mb-3.5 flex items-center justify-between"><h2 class="text-[.8rem] font-semibold text-[#667085]">Active users</h2><span aria-hidden="true" class="flex size-9 items-center justify-center rounded-[10px] bg-[#effdf4] text-base">👥</span></div>
    <p class="text-[1.75rem] font-extrabold tracking-[-.03em] text-[#101828]">18,442</p>
    <p class="mt-2 mb-3.5 inline-flex items-center gap-1 rounded-full bg-[#e8f8ee] px-[9px] py-[3px] text-[.75rem] font-bold text-[#15803d]"><span aria-hidden="true">▲</span><span class="sr-only">Up</span> 3.1% <span class="font-medium text-[#5d6679]">vs last month</span></p>
    <div role="img" aria-label="Last seven months, trending up" class="flex h-[38px] items-end gap-1 [&>i]:flex-1 [&>i]:rounded-t-[3px] [&>i]:bg-[#e3e9f2]"><i class="h-[55%]"></i><i class="h-[58%]"></i><i class="h-[50%]"></i><i class="h-[64%]"></i><i class="h-[61%]"></i><i class="h-[70%]"></i><i class="h-[76%] bg-[#16a34a]!"></i></div>
  </article>
  <article class="w-[250px] rounded-2xl border border-[#e9ecf1] bg-white px-[22px] pt-[22px] pb-[18px] transition-[translate,box-shadow] duration-[180ms] hover:-translate-y-1 hover:shadow-[0_18px_36px_-16px_rgba(16,24,40,.16)] motion-reduce:transition-none motion-reduce:hover:translate-y-0">
    <div class="mb-3.5 flex items-center justify-between"><h2 class="text-[.8rem] font-semibold text-[#667085]">Conversion rate</h2><span aria-hidden="true" class="flex size-9 items-center justify-center rounded-[10px] bg-[#fdf2f8] text-base">📉</span></div>
    <p class="text-[1.75rem] font-extrabold tracking-[-.03em] text-[#101828]">2.8%</p>
    <p class="mt-2 mb-3.5 inline-flex items-center gap-1 rounded-full bg-[#feecec] px-[9px] py-[3px] text-[.75rem] font-bold text-[#b91c1c]"><span aria-hidden="true">▼</span><span class="sr-only">Down</span> 0.4pt <span class="font-medium text-[#5d6679]">vs last month</span></p>
    <div role="img" aria-label="Last seven months, trending down" class="flex h-[38px] items-end gap-1 [&>i]:flex-1 [&>i]:rounded-t-[3px] [&>i]:bg-[#e3e9f2]"><i class="h-[80%]"></i><i class="h-[72%]"></i><i class="h-[75%]"></i><i class="h-[60%]"></i><i class="h-[52%]"></i><i class="h-[45%]"></i><i class="h-[38%] bg-[#db2777]!"></i></div>
  </article>
</div>

About this set

Three dashboard KPI cards: Revenue, Active users and Conversion rate. Each card has a label, an emoji icon on a tinted tile, a large figure, a green or red pill with the change against last month, and a seven-bar sparkline whose last bar is highlighted in the card’s accent colour. The sparkline needs no chart library and no SVG: it is a flex row of empty elements aligned to the bottom, each with an inline height percentage, and the highlighted bar takes its colour from currentColor so one class sets the accent. The up and down arrows are hidden from screen readers and replaced with the words Up and Down, and each sparkline is a role=”img” with a short description of its trend. Use these at the top of admin dashboards, analytics pages or reports; set the bar heights from your data on the server or with a line of script. Cards lift slightly on hover. The third card shows a falling conversion rate in red, because for that metric a drop is bad news. The Bootstrap version uses .card and .badge in a .row-cols-auto grid.

What’s included

  • Sparkline built from plain elements with percentage heights
  • Accent colour set once through currentColor
  • Up and down change pills with screen-reader words in place of arrows
  • Label as a heading, figure and comparison period on every card
  • No JavaScript; hover lift is off under prefers-reduced-motion

Accessibility

Each card is headed by its metric name, the arrow glyphs are aria-hidden with visually hidden Up or Down text beside them, and each sparkline has role="img" with a label such as Last seven months, trending up. The vs last month caption was darkened to pass 4.5:1 on both pill colours, and the hover lift is turned off under prefers-reduced-motion.

Customise it

Set the accent per card with .sc-s1, .sc-s2 and .sc-s3, the pill colours in .sc-up and .sc-down, and the bar heights in the inline styles. In Bootstrap the pill text colour is --bs-badge-color on .sc-up and .sc-down; in Tailwind change the h-[..%] classes and the highlighted bar's bg- utility.