Technology Apr 16, 2026 · 3 min read

Building Charts with Pure CSS — No SVG, No Canvas, No JS Required

Most developers reach for a chart library the moment they need a visualization — Chart.js, Recharts, D3 — and suddenly their page is carrying a hefty bundle just to draw a few lines. What if CSS alone could handle it? That's exactly what st-core.fscss pulls off. It renders fully functional line c...

DE
DEV Community
by Muhammad Sheraz
Building Charts with Pure CSS — No SVG, No Canvas, No JS Required

chart tempelate image

Most developers reach for a chart library the moment they need a visualization — Chart.js, Recharts, D3 — and suddenly their page is carrying a hefty bundle just to draw a few lines. What if CSS alone could handle it?

That's exactly what st-core.fscss pulls off. It renders fully functional line charts using nothing but browser-native CSS features, compiled at build time.

The Mechanism Behind It

Three CSS primitives do all the heavy lifting:

  • clip-path: polygon() — shapes each line visually
  • CSS custom properties (--st-p1 through --st-p8) — hold the data points
  • FSCSS mixins — generate the chart structure during compilation

The data pipeline looks like this:

data → CSS variables → clip-path → rendered chart

Everything is resolved before the browser even touches it. No runtime rendering, no extra DOM depth, no JavaScript dependency for visuals.

Rendering Multiple Lines

The multi-line chart is a great showcase of how elegantly this scales. The approach uses one shared renderer with per-element data overrides — each line element carries its own dataset via scoped CSS variables.

<script src="https://cdn.jsdelivr.net/npm/fscss@1.1.24/exec.min.js" async></script>

<style>
@import((*) from st-core)

@st-root()

.chart {
  height: 200px;
  position: relative;
  @st-chart-points(20, 25, 21, 37, 30, 60, 27, 50)
}

@st-chart-line(.chart-line)

.chart-line {
  background: currentColor;
  @st-chart-line-width(2px);
}

.line-1 { color: #32D8D4; }

.line-2 {
  color: #E8A030;
  @st-chart-points(10, 20, 16, 15, 66, 50, 80, 54)
}

.line-3 {
  color: #B840C8;
  @st-chart-points(5, 39, 20, 30, 27, 70, 60, 70)
}

@st-chart-grid(.chart-grid, 10, 7)
@st-chart-axis-y(.y-axis)
@st-chart-axis-x(.x-axis)
</style>

<div class="chart">
  <div class="chart-line line-1"></div>
  <div class="chart-line line-2"></div>
  <div class="chart-line line-3"></div>
  <div class="chart-grid"></div>
  <div class="y-axis">
    <span>0</span><span>20</span><span>40</span>
    <span>60</span><span>80</span><span>100</span>
  </div>
</div>

<div class="x-axis">
  <span>Sun</span><span>Mon</span><span>Tue</span>
  <span>Wed</span><span>Thu</span><span>Fri</span><span>Sat</span>
</div>

Each .line-* element overrides the default dataset from .chart. The renderer picks up whichever --st-p* variables are in scope for that element. Clean, composable, predictable.

Available Mixins at a Glance

Mixin What it renders
@st-chart-line Line path renderer
@st-chart-fill Area fill beneath the line
@st-chart-dot Data point markers
@st-chart-grid Background grid overlay
@st-chart-axis-x / @st-chart-axis-y Axis label layouts

All of these compile down to plain CSS — nothing ships to the browser that wasn't already resolved.

Handling Dynamic Data

For use cases where data changes at runtime, you can push updated values directly from JavaScript:

chart.style.cssText = `
  --st-p1: 40%;
  --st-p2: 75%;
  --st-p3: 60%;
`;

JavaScript passes the values; CSS renders the result. Transitions work as expected if you've defined them — no additional wiring needed.

Why This Approach Stands Out

  • Zero runtime overhead — charts are compiled into static CSS, not computed on each render
  • No third-party bundle — the browser's rendering engine does the visual work natively
  • Plain custom properties — data lives in CSS, not buried inside a config object or framework component
  • Full stylistic control — nothing is locked into a preset theme or opinionated design system

Try It

Live demo: fscss-ttr.github.io/st-core.fscss/multi-chart

Source: github.com/fscss-ttr/st-core.fscss

It's a refreshingly minimal take on data visualization — no installs, no configuration overhead, just CSS doing what it was always capable of.

DE
Source

This article was originally published by DEV Community and written by Muhammad Sheraz.

Read original article on DEV Community
Back to Discover

Reading List