Chart 14 of 15

KPI tiles

Use them for the three to eight numbers someone should see first. Always pair the value with a change (arrow, size and period in words) and use the skeleton while data loads.

Live demo

Made-up data. Try the options, then switch to the empty and one-point states.

Tiles can be plain or links. Direction is shown with ▲/▼ and words; colour only says whether the change is good or bad.

How to use it

JavaScript
const tile = (label, value, delta, goodWhen, values) =>
  h('div', { class: 'kt' },
    h('span', { class: 's' }, label),
    h('span', { class: 'v' }, value),
    h('span', { class: 'd ' + (delta === 0 ? 'flat' : (delta > 0) === (goodWhen === 'up') ? 'good' : 'bad') },
      (delta > 0 ? '▲ ' : '▼ ') + Math.abs(delta) + '% vs last month'),
    spark(values, { w: 160, h: 30, label: label + ' trend' }));

grid.append(tile('Spent this month', '£2,310', 6, 'down', last6));

// loading state
h('div', { class: 'kt' }, h('div', { class: 'skel', style: 'height:1.4rem;width:60%' }));

Options

.kgrid
A 4-column grid (2 on a phone) with 1px dividers. Children are .kt tiles.
.kt
Tile: .s label, .v value, .d change (.good or .bad), optional spark(). Use <a class='kt'> for links.
.skel
Shimmer placeholder while loading; respects prefers-reduced-motion.