webdevpuneet.com

Grouped Bar Chart — Clustered Multi-Series Bars

Grouped Bar Chart · Charts · Plain HTML, CSS & JS · Live preview

CategoryCharts

Copy & paste

Source Code

<div class="gb-card">
  <div class="gb-head"><h3>Revenue by quarter</h3></div>
  <div class="gb-legend" id="gbLegend"></div>
  <div class="gb-chart" id="gbChart"></div>
  <div class="gb-tip" id="gbTip" hidden></div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), 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

Clustered series
Multiple series side by side within each category.
Flexbox heights
Percentage heights — no SVG or coordinate math.
Clean y-scale
Max rounds up so the tallest bar fits neatly.
Color-coded legend
Each series keeps one color across all groups.
Animated growth
Bars rise from zero on load via CSS transition.
Hover tooltips
Cursor-following tip with category, series, and value.
Responsive
The browser's layout makes it fluid by default.
No library
Pure HTML/CSS/JS — no chart dependency.

About this UI Snippet

Grouped Bar Chart — Clustered Multi-Series Bars with Tooltips

Screenshot of the Grouped Bar Chart snippet rendered live

A grouped bar chart (also called a clustered bar chart) places several series side by side within each category, so you can compare both across categories and between series at a glance — sales across years per quarter, scores per metric, and the like. This snippet builds one with pure HTML and CSS bars, animated growth, a legend, and tooltips, in plain HTML, CSS, and vanilla JavaScript — no SVG, no chart library.

Flexbox layout, no coordinate math

Each category is a flex column; inside it the series bars sit in a row, bottom-aligned. Bar heights are simple percentages of the chart height (value / max), so there's no axis or pixel math — the browser's layout engine does the work, and the chart is naturally responsive. The y-scale rounds the maximum up to a clean number so the tallest bar doesn't touch the top.

Consistent color encoding

Each series gets one colour used for its bar in every group, and the legend ties colours to series names. This is the whole point of a grouped chart: the eye follows a colour across categories to read a trend ("the amber series climbs every quarter") while still comparing the cluster within each category.

Animated growth

Bars start at zero height and animate up to their value on load via a CSS transition triggered on the next frame — a small touch that draws attention to the data and reads as "this just rendered." A subtle brightness lift on hover gives per-bar feedback.

Cursor-following tooltips

Hovering any bar shows a tooltip with the category, series, and value, positioned relative to the card and following the pointer. Because tooltips are driven by simple mouse coordinates rather than chart geometry, they're robust at any size and easy to extend with more detail.

Data-driven and portable

Series are defined once (name, color) and groups are { label, values }, so adding a series or a category is a data edit — the bars, legend, scale, and tooltips all derive from it. With no SVG or dependency, it's a clean, lightweight reference for the clustered-bar pattern that's easy to drop into any dashboard.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA grouped bar chart renders with three series across four quarters.
  2. 2
    Use your dataEdit SERIES (name + color) and GROUPS ({ label, values }).
  3. 3
    Watch it animateBars grow from zero to their value on load.
  4. 4
    Hover a barA tooltip shows the category, series, and value.
  5. 5
    Read by colorFollow a series color across groups to spot trends.
  6. 6
    RestyleChange colors, bar width, gap, or chart height.

Real-world uses

Common Use Cases

Year-over-year comparison
Compare quarters across years in one chart, with side-by-side bars per quarter so both the season and the trend are readable.
A/B and variant results
Show a metric per variant side by side for each segment, with one colour per variant kept consistent across every group.
Survey breakdowns by segment
Compare how segments answered each question, using percentage heights from flexbox so the chart needs no SVG or coordinate maths.
Team and region KPIs
Cluster KPIs per group in a dashboard beside a metric card grid. The y-scale rounds up so the tallest bar fits neatly.
Budget versus actual
Pair planned and actual bars for each category so overspend is visible immediately, and use the simpler bar chart when there is only one series.
Related: Range Area Chart
See the Range Area Chart for a related charts pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

For a grouped bar chart, CSS flexbox is simpler and naturally responsive: each bar is a div whose height is a percentage of the container, so there is no viewBox, no coordinate mapping, and no manual resize handling. SVG shines for curves, arcs, and precise axes; for rectangular bars, letting the layout engine size them keeps the code short and fluid.

The script finds the maximum value across all series and rounds it up to the next ten, then every bar's height is value divided by that maximum, as a percentage. Rounding up gives headroom so the tallest bar does not touch the top edge and the proportions stay readable. You can change the rounding granularity to suit your data range.

Grouping places each series next to the others within a category, so you compare series within a group directly, while consistent per-series colors let you track one series across categories to see its trend. It answers two questions at once — "which is biggest here?" and "how does this series change over time?" — which a single-series or stacked chart cannot.

Add an entry to SERIES (a name and color) and a matching value to each group's values array; or add a group with its own label and values. The legend, scale, bars, and tooltips all derive from these arrays, so no other code changes. Keep each group's values array the same length as SERIES.

Map your series and groups to elements in JSX/templates, setting each bar's height from value/max as an inline style. Trigger the grow animation with a mounted effect or a CSS class toggled after render. Track hover state for the tooltip. Recharts or Chart.js can replace the rendering, but the data shape stays the same. Tailwind users apply heights and colors with utilities.