Chart
A bar chart built from a native <table> only,
the most semantically correct element for tabular data. No
wrapper elements, no SVG, no JavaScript.
Default
Each category is its own <tr> with a
<th scope="row"> label and a single
<td> value, the correct pairing for this data.
grid-auto-flow: column lays those rows out side by
side so each one renders as a vertical bar, while assistive tech
still reads them in their natural row order. Set --v
on each <td> to its value as a percentage of
--chart-height. The y-axis scale is a
<ul> nested inside <caption>,
the only element a table permits outside of rows. Column headers
become redundant once every row has its own label, so they are
visually hidden but kept for structure.
| 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>