A bar chart that is a plain <table>. No wrapper
elements, no SVG, no JavaScript.
Composed of
Table- The native table the chart is built on
Standalone
<link rel="stylesheet" href="https://esm.sh/@erikt/ui/chart.css" />
Default
Each category is one <tr> holding a
<th scope="row"> label and a single
<td> value. grid-auto-flow: column
turns those rows sideways so each renders as a vertical bar, and a
screen reader still walks them row by row. Set --v on
each <td> to its value as a percentage of
--chart-height.
The y-axis is a <ul> inside
<caption>, the one place a table allows content
outside its rows. The column headers are redundant once every row is
labelled, so they stay in the markup but are hidden visually.
| Month | Signups |
|---|---|
| 01 | 29 |
| 02 | 52 |
| 03 | 34 |
| 04 | 16 |
| 05 | 43 |
| 06 | 23 |
| 07 | 25 |
| 08 | 30 |
| 09 | 8 |
| 10 | 43 |
| 11 | 37 |
| 12 | 31 |
<table class="chart">
<caption>
Signups by month
<ul class="chart-y-axis" aria-hidden="true">
<li>60</li>
<li>40</li>
<li>20</li>
<li>0</li>
</ul>
</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Signups</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">01</th>
<td style="--v: 29"><span>29</span></td>
</tr>
<tr>
<th scope="row">02</th>
<td style="--v: 52"><span>52</span></td>
</tr>
</tbody>
</table>
API reference
| Type | Classes / attributes | What it does |
|---|---|---|
| Value | --v: 52 |
Bar height as a percentage, set on each td |
| Height | --chart-height: 16rem |
Height of the plot area |
| Color | --chart-color: var(--ui-color2-500) |
Bar color |
| Axis | .chart-y-axis |
A ul inside caption that renders the y-axis labels |