WCAG requirements for charts, criterion by criterion

Which of the 55 WCAG 2.2 A/AA success criteria actually bite for a chart — what each means in practice, and how to check it.

Most WCAG criteria are page-level and land on the embedding application. But a chart is an interactive, graphical, data-dense component, so an unusually large slice of the standard applies inside the component boundary. These are the ones that decide whether your data views pass an audit.

The load-bearing criteria

CriterionWhat it means for a chartHow to verify
1.1.1 Non-text Content (A) The rendered graphic needs a text alternative that carries the data, not a caption. A one-line label is not an alternative for a thousand points; a structured data table + a summary sentence is. Turn the screen reader on: can you get actual values without seeing pixels?
1.3.1 Info & Relationships (A) Series/point structure must exist programmatically — table headers scoped, legend entries related to series, not just visually adjacent text. Inspect the accessibility tree; check the table has real <th> headers.
1.4.1 Use of Color (A) Series can't be distinguishable by hue alone — dash patterns, markers, or direct labels are the second channel ("double encoding"). Grayscale the chart: can you still tell series apart?
1.4.3 / 1.4.11 Contrast (AA) 1.4.3 covers text (ticks, labels: ≥4.5:1). 1.4.11 covers the marks themselves — lines, bars, focus indicators need ≥3:1 against the background. Canvas pixels are not exempt. Compute ratios for the actual rendered colors on the actual background.
1.4.4 / 1.4.10 Resize & Reflow (AA) 200% zoom and 320px-wide viewports must not clip or overlap — tick labels thin out, legends wrap, containers stay fluid. Zoom to 200%; resize to 320px; look for loss of content or function.
2.1.1 / 2.1.2 Keyboard (A) Everything pointer does needs a keyboard path: move between data points, switch series, zoom (+/- for wheel), pan — and focus must never get trapped inside the chart. Unplug the mouse. Reach every value, then Tab out cleanly.
2.4.7 Focus Visible (AA) The focused chart surface (and every control) shows a visible ring. Tab through; the focus position must always be visually obvious.
2.5.7 Dragging Movements (AA) Drag-to-pan needs a single-pointer alternative (pager buttons, click-to-step). Pan the chart without ever dragging.
2.5.8 Target Size (AA) Legend toggles, pagers, export buttons: ≥24×24 CSS px (or spacing equivalent). Measure the interactive targets.
4.1.2 Name, Role, Value (A) The chart surface has an accessible name and role; legend toggles expose pressed state; the focused point's value is programmatically determinable. Read the accessibility tree, not the DOM.
4.1.3 Status Messages (AA) Value announcements as the cursor moves must flow through a live region — without stealing focus, and debounced so key-repeat doesn't flood the reader. Hold an arrow key with a screen reader running; listen.
3.1.2 Language of Parts (AA) If the page is German, the chart's own UI prose (keyboard help, summary, captions) should be German too — untagged English passages fail. Localize the chart's fixed strings alongside your app.
Why an axe scan isn't enough: nearly everything in this table is functional — keyboard behavior, spoken announcements, computed contrast on rendered pixels, table parity with the data. Automated scanners check markup, and a canvas chart barely has any: a completely inaccessible canvas scores zero axe violations. Scanner-clean is necessary, never sufficient. The checks have to exercise the chart — that's what a functional chart audit does.

From criteria to paperwork: VPAT, ACR, EN 301 549, Section 508

Procurement doesn't ask "is it accessible" — it asks for an ACR (Accessibility Conformance Report, written on the ITI VPAT® template) stating per-criterion conformance: Supports / Partially Supports / Does Not Support / Not Applicable. The same WCAG substance is referenced by EN 301 549 in the EU (the standard behind the European Accessibility Act) and Section 508 for US federal buyers — one evidence base, three editions of the report.

Two things make a chart-layer ACR credible: scoping honesty (the chart component answers for itself; page-level criteria belong to the host app) and evidence freshness (a report generated from checks that run on every commit beats a PDF written once a year). fcharts generates its ACR — all three editions, Markdown/HTML/JSON — from the committed audit on every build; here's the live sample, and fcharts-audit --compare diffs two of them so a buyer sees exactly what changed between versions.