AXS-65Recommended
Give every chart a summary and its numbers
Give every chart a short name, a caption that states its main finding, and the numbers behind it as a table or a download. This is WCAG criterion 1.1.1 (A).
How to do it
The W3C tutorial on complex images splits the text alternative in two parts. A short one names the chart, and a long one carries the data. Put the chart in a figure whose figcaption says what the reader should take away. Put the numbers in a table under it or inside a details element, built as Give tables headers says. Give an SVG chart role="img" and an aria-label, and a canvas chart fallback text. Avoid aria-describedby for the data, since screen readers read the target as one paragraph and lose the table. Lines and bars also need a second cue besides colour, as Never use colour as the only signal says.
Examples
HTML example
<figure class="chart">
<svg role="img" aria-label="Monthly orders, January to June">…</svg>
<figcaption>Orders grew from 120 in January to 310 in June.</figcaption>
<details>
<summary>Show the numbers</summary>
<table>
<thead><tr><th scope="col">Month</th><th scope="col">Orders</th></tr></thead>
<tbody><tr><th scope="row">January</th><td>120</td></tr></tbody>
</table>
</details>
</figure>
JavaScript example
// Playwright: every chart has a name and its data nearby
for (const chart of await page.locator('svg[role="img"], canvas, img.chart').all()) {
await expect(chart).toHaveAccessibleName(/\S/);
const figure = chart.locator('xpath=ancestor::figure[1]');
await expect(figure.locator('figcaption')).toHaveCount(1);
expect(await figure.locator('table, a[href$=".csv"]').count()).toBeGreaterThan(0);
}
Python example
# Playwright for Python: the same check
for chart in page.locator('svg[role="img"], canvas, img.chart').all():
expect(chart).to_have_accessible_name(re.compile(r"\S"))
figure = chart.locator("xpath=ancestor::figure[1]")
expect(figure.locator("figcaption")).to_have_count(1)
assert figure.locator('table, a[href$=".csv"]').count() > 0
How to check
A browser test finds every chart (canvas, chart svg or chart image) on each page type. Each has a non-empty accessible name and sits in a figure that holds a figcaption and a table or a link to the data.
Sources
Related rules
- AXS-22 Give tables headers in Accessibility
- AXS-4 Never use colour as the only signal in Accessibility
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/accessibility/seeing-and-reading/chart-alternatives">Agent Wranglers accessibility playbook</a>. In code you write, add a comment next to it with the same link.