153Bar charts
The workhorse: comparison and time. Bars are ≤24px thick with a rounded data-end and a square baseline, grow from zero on load, and the whole column is the tooltip's hit target.
Column — single series
One series needs no legend: the title names it. Hover for the tooltip; bars animate up on load (and hold still under reduced motion).
markup
<figure class="ns-chart">
<div class="ns-chart__head"><span class="ns-chart__title">Course completions</span><span class="ns-chart__sub">weekly</span></div>
<div class="ns-chart__plot">
<div class="ns-chart__col" tabindex="0" style="--v:38%">
<span class="ns-chart__tip">W1 · 38</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:52%">
<span class="ns-chart__tip">W2 · 52</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:46%">
<span class="ns-chart__tip">W3 · 46</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:64%">
<span class="ns-chart__tip">W4 · 64</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:58%">
<span class="ns-chart__tip">W5 · 58</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:82%">
<span class="ns-chart__tip">W6 · 82</span>
<div class="ns-chart__bar"></div>
</div>
</div>
<div class="ns-chart__x"><span>W1</span><span>W2</span><span>W3</span><span>W4</span><span>W5</span><span>W6</span></div>
</figure>Sizes
Three plot heights: sm for cards and rails, md default, lg for a dashboard's lead chart.
markup
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(14rem,100%),1fr));gap:var(--gap-grid);inline-size:100%">
<figure class="ns-chart ns-chart--sm">
<div class="ns-chart__head"><span class="ns-chart__title">Small</span><span class="ns-chart__sub">6rem</span></div>
<div class="ns-chart__plot">
<div class="ns-chart__col" tabindex="0" style="--v:38%">
<span class="ns-chart__tip">W1 · 38</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:52%">
<span class="ns-chart__tip">W2 · 52</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:46%">
<span class="ns-chart__tip">W3 · 46</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:64%">
<span class="ns-chart__tip">W4 · 64</span>
<div class="ns-chart__bar"></div>
</div>
</div>
</figure>
<figure class="ns-chart">
<div class="ns-chart__head"><span class="ns-chart__title">Medium</span><span class="ns-chart__sub">10rem · default</span></div>
<div class="ns-chart__plot">
<div class="ns-chart__col" tabindex="0" style="--v:38%">
<span class="ns-chart__tip">W1 · 38</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:52%">
<span class="ns-chart__tip">W2 · 52</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:46%">
<span class="ns-chart__tip">W3 · 46</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:64%">
<span class="ns-chart__tip">W4 · 64</span>
<div class="ns-chart__bar"></div>
</div>
</div>
</figure>
<figure class="ns-chart ns-chart--lg">
<div class="ns-chart__head"><span class="ns-chart__title">Large</span><span class="ns-chart__sub">15rem</span></div>
<div class="ns-chart__plot">
<div class="ns-chart__col" tabindex="0" style="--v:38%">
<span class="ns-chart__tip">W1 · 38</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:52%">
<span class="ns-chart__tip">W2 · 52</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:46%">
<span class="ns-chart__tip">W3 · 46</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:64%">
<span class="ns-chart__tip">W4 · 64</span>
<div class="ns-chart__bar"></div>
</div>
</div>
</figure>
</div>Grouped
Two series per band, separated by the 2px surface gap — never a stroke. Legend is mandatory from the second series on.
- Admin track
- Developer track
markup
<figure class="ns-chart">
<div class="ns-chart__head">
<span class="ns-chart__title">Course completions</span>
<span class="ns-chart__sub">weekly · last 6 weeks</span>
</div>
<ul class="ns-chart__legend">
<li class="ns-chart__key" data-c="1"><span class="ns-chart__swatch"></span>Admin track</li>
<li class="ns-chart__key" data-c="2"><span class="ns-chart__swatch"></span>Developer track</li>
</ul>
<div class="ns-chart__frame">
<div class="ns-chart__y"><span>0</span><span>25</span><span>50</span><span>75</span><span>100</span></div>
<div class="ns-chart__plot">
<div class="ns-chart__col ns-chart__col--group" tabindex="0">
<span class="ns-chart__tip" style="--v:38%">W1 · admin 38 · dev 24</span>
<div class="ns-chart__bar" data-c="1" style="--v:38%"></div>
<div class="ns-chart__bar" data-c="2" style="--v:24%"></div>
</div>
<div class="ns-chart__col ns-chart__col--group" tabindex="0">
<span class="ns-chart__tip" style="--v:52%">W2 · admin 52 · dev 30</span>
<div class="ns-chart__bar" data-c="1" style="--v:52%"></div>
<div class="ns-chart__bar" data-c="2" style="--v:30%"></div>
</div>
<div class="ns-chart__col ns-chart__col--group" tabindex="0">
<span class="ns-chart__tip" style="--v:46%">W3 · admin 46 · dev 41</span>
<div class="ns-chart__bar" data-c="1" style="--v:46%"></div>
<div class="ns-chart__bar" data-c="2" style="--v:41%"></div>
</div>
<div class="ns-chart__col ns-chart__col--group" tabindex="0">
<span class="ns-chart__tip" style="--v:64%">W4 · admin 64 · dev 38</span>
<div class="ns-chart__bar" data-c="1" style="--v:64%"></div>
<div class="ns-chart__bar" data-c="2" style="--v:38%"></div>
</div>
<div class="ns-chart__col ns-chart__col--group" tabindex="0">
<span class="ns-chart__tip" style="--v:58%">W5 · admin 58 · dev 52</span>
<div class="ns-chart__bar" data-c="1" style="--v:58%"></div>
<div class="ns-chart__bar" data-c="2" style="--v:52%"></div>
</div>
<div class="ns-chart__col ns-chart__col--group" tabindex="0">
<span class="ns-chart__tip" style="--v:82%">W6 · admin 82 · dev 61</span>
<div class="ns-chart__bar" data-c="1" style="--v:82%"></div>
<div class="ns-chart__bar" data-c="2" style="--v:61%"></div>
</div>
</div>
<div class="ns-chart__x"><span>W1</span><span>W2</span><span>W3</span><span>W4</span><span>W5</span><span>W6</span></div>
</div>
</figure>Stacked
Parts of a whole over time. Segments stack bottom-up in slot order with the surface gap between them; only the top segment gets the rounded end.
- Video
- Reading
- Lab
markup
<figure class="ns-chart">
<div class="ns-chart__head"><span class="ns-chart__title">Lessons completed by type</span><span class="ns-chart__sub">weekly</span></div>
<ul class="ns-chart__legend">
<li class="ns-chart__key" data-c="1"><span class="ns-chart__swatch"></span>Video</li>
<li class="ns-chart__key" data-c="2"><span class="ns-chart__swatch"></span>Reading</li>
<li class="ns-chart__key" data-c="3"><span class="ns-chart__swatch"></span>Lab</li>
</ul>
<div class="ns-chart__plot">
<div class="ns-chart__col" tabindex="0">
<span class="ns-chart__tip" style="--v:60%">W1 · 60 total</span>
<div class="ns-chart__stack">
<div class="ns-chart__seg" data-c="1" style="--v:30%"></div>
<div class="ns-chart__seg" data-c="2" style="--v:18%"></div>
<div class="ns-chart__seg" data-c="3" style="--v:12%"></div>
</div>
</div>
<div class="ns-chart__col" tabindex="0">
<span class="ns-chart__tip" style="--v:68%">W2 · 68 total</span>
<div class="ns-chart__stack">
<div class="ns-chart__seg" data-c="1" style="--v:36%"></div>
<div class="ns-chart__seg" data-c="2" style="--v:22%"></div>
<div class="ns-chart__seg" data-c="3" style="--v:10%"></div>
</div>
</div>
<div class="ns-chart__col" tabindex="0">
<span class="ns-chart__tip" style="--v:62%">W3 · 62 total</span>
<div class="ns-chart__stack">
<div class="ns-chart__seg" data-c="1" style="--v:28%"></div>
<div class="ns-chart__seg" data-c="2" style="--v:16%"></div>
<div class="ns-chart__seg" data-c="3" style="--v:18%"></div>
</div>
</div>
<div class="ns-chart__col" tabindex="0">
<span class="ns-chart__tip" style="--v:78%">W4 · 78 total</span>
<div class="ns-chart__stack">
<div class="ns-chart__seg" data-c="1" style="--v:44%"></div>
<div class="ns-chart__seg" data-c="2" style="--v:20%"></div>
<div class="ns-chart__seg" data-c="3" style="--v:14%"></div>
</div>
</div>
</div>
<div class="ns-chart__x"><span>W1</span><span>W2</span><span>W3</span><span>W4</span></div>
</figure>Horizontal
For ranked entities with real names — the label column keeps them readable. Bars slide in from the left; hover a row for its tooltip.
markup
<figure class="ns-chart">
<div class="ns-chart__head"><span class="ns-chart__title">Enrollments by course</span><span class="ns-chart__sub">this quarter</span></div>
<div class="ns-chart__rows">
<div class="ns-chart__row" tabindex="0">
<span class="ns-chart__tip" style="--v:92%">Apex basics · 460</span>
<span class="ns-chart__row-label">Apex basics</span>
<div><div class="ns-chart__hbar" data-c="1" style="--v:92%"></div></div>
<span class="ns-chart__row-value">460</span>
</div>
<div class="ns-chart__row" tabindex="0">
<span class="ns-chart__tip" style="--v:74%">Admin cert · 371</span>
<span class="ns-chart__row-label">Admin cert</span>
<div><div class="ns-chart__hbar" data-c="1" style="--v:74%"></div></div>
<span class="ns-chart__row-value">371</span>
</div>
<div class="ns-chart__row" tabindex="0">
<span class="ns-chart__tip" style="--v:58%">Flows · 290</span>
<span class="ns-chart__row-label">Flows</span>
<div><div class="ns-chart__hbar" data-c="1" style="--v:58%"></div></div>
<span class="ns-chart__row-value">290</span>
</div>
<div class="ns-chart__row" tabindex="0">
<span class="ns-chart__tip" style="--v:41%">LWC · 205</span>
<span class="ns-chart__row-label">LWC</span>
<div><div class="ns-chart__hbar" data-c="1" style="--v:41%"></div></div>
<span class="ns-chart__row-value">205</span>
</div>
<div class="ns-chart__row" tabindex="0">
<span class="ns-chart__tip" style="--v:26%">SOQL · 131</span>
<span class="ns-chart__row-label">SOQL</span>
<div><div class="ns-chart__hbar" data-c="1" style="--v:26%"></div></div>
<span class="ns-chart__row-value">131</span>
</div>
</div>
</figure>Diverging
Above/below a baseline — cool arm up, warm arm down, from the diverging ramp. Never status red/green: polarity is not health.
markup
<figure class="ns-chart">
<div class="ns-chart__head"><span class="ns-chart__title">Enrollment change vs last month</span><span class="ns-chart__sub">by course</span></div>
<div class="ns-chart__rows">
<div class="ns-chart__row" tabindex="0">
<span class="ns-chart__tip" style="--v:64%">Apex basics · +32%</span>
<span class="ns-chart__row-label">Apex basics</span>
<div><div class="ns-chart__hbar" data-pole="up" style="--v:64%"></div></div>
<span class="ns-chart__row-value">+32%</span>
</div>
<div class="ns-chart__row" tabindex="0">
<span class="ns-chart__tip" style="--v:38%">Flows · +19%</span>
<span class="ns-chart__row-label">Flows</span>
<div><div class="ns-chart__hbar" data-pole="up" style="--v:38%"></div></div>
<span class="ns-chart__row-value">+19%</span>
</div>
<div class="ns-chart__row" tabindex="0">
<span class="ns-chart__tip" style="--v:22%">Admin cert · −11%</span>
<span class="ns-chart__row-label">Admin cert</span>
<div><div class="ns-chart__hbar" data-pole="down" style="--v:22%"></div></div>
<span class="ns-chart__row-value">−11%</span>
</div>
<div class="ns-chart__row" tabindex="0">
<span class="ns-chart__tip" style="--v:46%">SOQL · −23%</span>
<span class="ns-chart__row-label">SOQL</span>
<div><div class="ns-chart__hbar" data-pole="down" style="--v:46%"></div></div>
<span class="ns-chart__row-value">−23%</span>
</div>
</div>
</figure>With trend line
A 2px line over the columns carries the trend; vector-effect keeps it 2px at any width. The line draws itself on load.
- Completions
- Trend
markup
<figure class="ns-chart">
<div class="ns-chart__head"><span class="ns-chart__title">Completions + 3-week trend</span><span class="ns-chart__sub">weekly</span></div>
<ul class="ns-chart__legend">
<li class="ns-chart__key" data-c="1"><span class="ns-chart__swatch"></span>Completions</li>
<li class="ns-chart__key" data-c="2"><span class="ns-chart__swatch ns-chart__swatch--line"></span>Trend</li>
</ul>
<div class="ns-chart__plot">
<div class="ns-chart__col" tabindex="0" style="--v:38%">
<span class="ns-chart__tip">W1 · 38</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:52%">
<span class="ns-chart__tip">W2 · 52</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:46%">
<span class="ns-chart__tip">W3 · 46</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:64%">
<span class="ns-chart__tip">W4 · 64</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:58%">
<span class="ns-chart__tip">W5 · 58</span>
<div class="ns-chart__bar"></div>
</div>
<div class="ns-chart__col" tabindex="0" style="--v:82%">
<span class="ns-chart__tip">W6 · 82</span>
<div class="ns-chart__bar"></div>
</div>
<svg class="ns-chart__svg" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true" style="position:absolute;inset:0;block-size:100%">
<polyline class="ns-chart__line ns-chart__line--draw" data-c="2" vector-effect="non-scaling-stroke" pathLength="1" points="8,60 25,50 41,53 58,40 75,44 92,22"/>
</svg>
</div>
<div class="ns-chart__x"><span>W1</span><span>W2</span><span>W3</span><span>W4</span><span>W5</span><span>W6</span></div>
</figure>