webdevpuneet.com

Stat Comparison Card — KPI Trend Card HTML CSS JS

Stat Comparison Card · Dashboards · Plain HTML, CSS & JS · Live preview

CategoryDashboards

Copy & paste

Source Code

<div class="scc-grid" id="sccGrid"></div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Period-over-period delta
Each card computes percent change against the previous period and shows it as a color-coded pill with a direction arrow.
Up / down / flat classification
Near-zero changes read as "flat" rather than a misleading precise arrow, so unchanged metrics look unchanged.
Direction-driven color
Color follows the change direction (not the value), and is easy to flip for metrics where down is good.
Per-metric formatting
fmtValue() renders currency, counts, percentages, and durations from a single fmt flag.
Inline SVG sparkline
A data-normalized path draws a mini trend line and filled area, colored to match the trend.
Fully data-driven
Value, delta, and sparkline all derive from one stat object — adding a KPI is one array entry.
Responsive auto-fit grid
Cards reflow from four across to one column on small screens automatically.
Tabular-aligned numbers
Values use tabular-nums so digits line up cleanly across cards.

About this UI Snippet

Stat Comparison Card — KPI Value with Period-Over-Period Change & Sparkline

Screenshot of the Stat Comparison Card snippet rendered live

Every analytics dashboard opens with a row of KPI cards, and a good one never shows a number in isolation — it shows the value, how it compares to last period, and the recent trend, so a glance answers "is this good and which way is it heading?" This snippet builds those stat comparison cards in plain HTML, CSS, and vanilla JavaScript: a big value, a color-coded percent-change pill with a direction arrow, a "vs last month" reference, and an inline SVG sparkline — all generated from data.

A number with context, not in a vacuum

Each card pairs the headline value with a delta computed against the previous period ((value − prev) / prev × 100). The delta renders as a pill — green with an up arrow for an increase, red with a down arrow for a decrease, gray with a flat line when essentially unchanged — plus the "vs last month" label so the comparison is explicit. This is the difference between "Revenue: $48,200" (which means nothing alone) and "$48,200, ▲15.3% vs last month" (which is a decision-ready insight).

Direction-aware, not just positive/negative

The card classifies the change into up, down, or *flat* — a change under a small threshold (0.05%) reads as "no real change" rather than a misleadingly precise "▲0.0%". This matters for metrics that hover (like average session time in the demo, which is unchanged): forcing every metric into up-or-down would imply movement that isn't there. And critically, color follows direction, not value — for a metric where down is good (like churn), you'd flip the tone, since "green = good" depends on the metric.

Smart per-metric formatting

Different KPIs need different formats, so fmtValue() handles currency ($48,200 with thousands separators), counts (1,284), percentages (3.8%), and durations (4m 24s) from a fmt flag on each stat. The value, the delta, and the sparkline all derive from the same data object, so a card is fully described by its data — adding a new KPI is one array entry, not new markup.

An inline sparkline built from a path

The mini trend chart is a tiny inline SVG. sparkPath() normalizes the data series to the chart's height (scaling between the series min and max so the shape fills the space), builds an M…L… line path, and closes it into a filled area below. The sparkline's color matches the trend direction, reinforcing the up/down signal visually — a falling metric gets a red line, a rising one green. It's drawn with preserveAspectRatio="none" so it stretches to the card width responsively, and at this size a sparkline conveys "the shape of recent history" far better than any axis-laden chart.

Responsive grid, drop-in ready

The cards sit in an auto-fit grid that reflows from four across down to one on narrow screens. Because everything is data-driven and self-contained, you populate STATS from your analytics API (current value, previous-period value, and a short series for the sparkline) and the whole row renders — values formatted, deltas computed, trends colored, sparklines drawn. The FAQs cover wiring real data and handling metrics where down is the good direction.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA responsive row of KPI cards renders — revenue, users, conversion, and session time — each with a value, change, and sparkline.
  2. 2
    Read the deltasEach card shows a colored pill: green ▲ for up, red ▼ for down, gray for essentially unchanged, vs last month.
  3. 3
    Note the sparklineThe mini trend line under each value matches the change color, showing the recent shape at a glance.
  4. 4
    Check the formattingValues format per metric — currency, counts, percentages, and durations — from the fmt flag.
  5. 5
    Edit the statsChange the STATS array (value, prev, fmt, icon, tone, spark) to your KPIs — cards regenerate.
  6. 6
    Connect real analyticsPopulate STATS from your analytics API with the current value, previous-period value, and a sparkline series.

Real-world uses

Common Use Cases

Analytics KPI summary rows
Top a dashboard with cards showing value, percent change versus the previous period and an inline trend line, answering is this good at a glance.
Revenue and sales overviews
Show revenue, orders and conversion rate side by side, with near-zero changes classed as flat rather than a misleading tiny arrow.
Marketing performance reports
Display traffic, leads and cost per acquisition, where colour follows the direction of the change and can be inverted for metrics where down is good.
Wider card grids
Place several cards inside a metric card grid and expand any tiny trend into a full sparkline chart.
SaaS health boards
Surface uptime, latency and ticket volume together, with fmtValue() handling currency, counts, percentages and durations in one consistent way.

Got questions?

Frequently Asked Questions

Populate the STATS array from your analytics API: each entry needs the current value, the previous-period value (prev) for the delta, a fmt flag for formatting, and a short numeric series (spark) for the sparkline. Fetch those on load (and on refresh), assign to STATS, and call render() — every card's value, delta, and trend recompute from the data.

For metrics like churn, bounce rate, or error count, "down" is positive, so invert the color logic for those cards — add an inverted flag to the stat and, when set, map a negative change to the green/up tone and a positive change to red/down. The percent and arrow stay the same; only the color tone flips to reflect that lower is better.

A metric that barely moved shouldn't display a precise "▲0.0%" with an up arrow, which implies meaningful growth. Treating changes below a small threshold as flat (gray, with a neutral line) honestly communicates "no real change," which is more useful than forcing every metric into up or down. Adjust the threshold to your tolerance.

sparkPath() finds the series min and max, normalizes each point to the chart height (so the line fills the vertical space regardless of the values' scale), and builds an SVG path with M/L commands, then closes a filled area below it. preserveAspectRatio="none" stretches it to the card width. Pass any-length series; the path adapts to the number of points.

In React, hold the stats in useState and compute each delta and sparkline path with useMemo, rendering cards with .map(); in Vue, use a computed over a reactive stats array; in Angular, use *ngFor with getters or pipes. The delta, formatting, and sparkline functions are plain JavaScript that port unchanged — only the per-data re-render moves into the framework.