Accessible Data Visualisation: How to Build Charts and Dashboards That Work Without Sight or a Mouse

A chart is a picture of a relationship. Most accessibility guidance treats it as a picture of nothing.
That is why the standard advice fails here. Add an alt attribute, the checklist says, and an automated scanner sees an SVG carrying an accessible name and moves on. A blind analyst opening the same dashboard hits a dead end: they now know a chart exists, and nothing else.
The gap is measurable. Industry surveys in 2026 put more than 70% of public-facing charts, graphs and dashboards beyond reach for users with visual, cognitive or motor impairments. Studies of screen reader users working with typical web visualisations have found them roughly 61% less accurate and taking around 211% longer on comparable tasks. Recent academic work has documented the same pattern in US government dashboards built for public use.
These are reported findings from particular studies, not universal constants. But the direction is consistent enough to plan against.
Five needs, five different fixes
The reason generic advice underdelivers is that "make the chart accessible" bundles five distinct problems whose solutions barely overlap.
No vision. A screen reader user does not need a description of the picture. They need the data, and a statement of what it shows. Prose describing "an upward trending blue line" is worse than useless: it is the visual encoding without the information.
Low vision. Magnification, contrast and reflow have to survive. A chart that becomes a horizontally scrolling smear at 400% zoom has failed, and dense multi-series charts are the worst offenders.
Colour vision deficiency. Around 8% of men have a red-green deficiency, deuteranomaly being the most common form, with red-green types accounting for roughly 98% of cases. Any meaning carried by hue alone disappears for them.
Keyboard and motor. Every filter, legend toggle, tab, tooltip trigger, drilldown and zoom control has to be reachable and operable without a mouse, with a focus indicator you can actually see.
Cognitive load, cutting across all four. A chart with eleven series, a dual axis and no stated takeaway is hard for everyone and excluding for many.
The principle that does the most work
For anything beyond a trivial chart, the accessible experience is not a longer alt text. It is a second representation of the same data.
This is the single idea that changes outcomes, and it is worth stating plainly because teams resist it. They keep trying to compress a scatter plot into an alt attribute. It cannot be done, and screen readers will not let a user pause, re-read or navigate within an alt attribute the way they can within a table.
Three alternative representations work, and they serve different purposes:
A properly marked up data table. Caption, <th> cells with scope, <thead> and <tbody>. This is the gold standard because it is navigable: a screen reader user can move cell by cell, hear row and column headers announced, and compare values in either direction. It can sit visually beneath the chart, inside a disclosure widget, or be visually hidden and exposed only to assistive technology, though a visible toggle is friendlier to sighted users with cognitive or low-vision needs too.
A short text summary. One or two sentences stating what the chart shows and what it means. "Monthly active users grew from 12,400 in January to 31,900 in June, with the steepest increase in April." This is the fastest path to the takeaway, and it benefits everyone. If you cannot write it, that is diagnostic: an undescribable chart usually has no point.
A downloadable CSV. The escape hatch for genuinely large datasets, where a table would be thousands of rows. Not a substitute for the other two, because it forces the user out of your product to answer a question your product should have answered.
Use the summary always, the table for anything a user might need exact values from, and the CSV when the dataset is too large to render.
Accessible names and descriptions, done properly
You still need the chart itself to be announced sensibly. The rules:
Decorative versus informative. A sparkline that repeats a number stated in text beside it is decorative. Mark it aria-hidden="true" and let the number speak. Not every chart needs an accessible name; a redundant one adds noise.
Short name, extended description. The accessible name says what the chart is ("Monthly active users, January to June 2026"). The extended description says what it shows. Do not cram the second into the first.
Inline SVG. Use role="img" with aria-label, or better, aria-labelledby pointing at a visible caption so sighted and non-sighted users get the same words. Support for the SVG <title> element remains inconsistent across screen readers, so do not rely on it alone.
The unlabelled path problem. An inline SVG left exposed presents assistive technology with a pile of unlabelled <path> elements, sometimes announced one by one. If the graphic is not itself keyboard navigable, hide it and expose the alternative:
<figure>
<figcaption id="chart-cap">
Monthly active users, January to June 2026
</figcaption>
<svg aria-hidden="true" focusable="false" viewBox="0 0 600 300">
<!-- visual rendering only -->
</svg>
<p>Users grew from 12,400 in January to 31,900 in June,
with the steepest rise in April.</p>
<details>
<summary>View data table</summary>
<table>
<caption>Monthly active users by month</caption>
<thead>
<tr><th scope="col">Month</th><th scope="col">Users</th></tr>
</thead>
<tbody>
<tr><th scope="row">January</th><td>12,400</td></tr>
<tr><th scope="row">February</th><td>15,100</td></tr>
</tbody>
</table>
</details>
</figure>
The chart is decoration. The figure carries the meaning.
Colour: redundancy, not replacement
The rule is not "avoid colour". It is never encode meaning in hue alone. Colour can stay; it just cannot be the only channel.
Four redundant encodings, roughly in order of effectiveness:
- Direct labelling. Put the series name at the end of the line instead of in a legend. This removes the colour-matching task entirely and is better for everyone.
- Line style. Solid, dashed, dotted.
- Marker shape. Circle, square, triangle at data points.
- Pattern fills. For bars and areas, an SVG
<pattern>separates series visually whilearia-labelcarries the same distinction to assistive technology.
<defs>
<pattern id="hatch" width="6" height="6"
patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
<line x1="0" y1="0" x2="0" y2="6" stroke="currentColor" stroke-width="3"/>
</pattern>
</defs>
<rect fill="url(#hatch)" x="10" y="40" width="40" height="160"/>
On contrast, two requirements apply and teams routinely satisfy only one. Text in and around the chart needs 4.5:1 against its background, 3:1 for large text. Separately, 1.4.11 Non-text Contrast requires 3:1 for graphical objects needed to understand the content: a line against the plot background, a bar against the canvas.
The rule most often missed: adjacent colours in a series need to differ from each other, not only from the background. Two similar blues in a stacked bar can each pass against white and still be indistinguishable where they meet.
Finally, insufficient contrast remains the most common accessibility failure on the web overall, present on roughly 83.6% of home pages in large-scale surveys. Charts are not an exception to that pattern. They are usually the worst part of the page.
Keyboard and interaction
This is where charting libraries most often fall down, because the visual layer got the attention and the interaction layer was assumed.
Every interactive affordance needs keyboard operation with a visible focus indicator: legend toggles, filters, tab strips, date range pickers, drilldowns, zoom and pan controls, and export buttons.
Data-point-level navigation - arrow keys moving focus through a series, each point announcing its label and value - is genuinely good when a library provides it. Building it from scratch is a substantial investment, and for most teams a well-marked-up data table delivers more benefit per hour. Take it if your library offers it; do not make it a prerequisite for shipping.
Tooltips are the recurring failure. A tooltip that appears only on hover excludes every keyboard user. It needs focus parity, and under 1.4.13 Content on Hover or Focus the content must be dismissible without moving focus (Escape), hoverable (the pointer can move onto it without it vanishing), and persistent until dismissed or no longer valid. Chart tooltips that follow the cursor and disappear on the smallest movement fail all three.
The WCAG 2.2 criteria that bite hardest
Worth naming explicitly, because these are the ones charts fail:
- 1.1.1 Non-text Content - the chart needs a text alternative that conveys the information, not the appearance
- 1.4.1 Use of Color - no meaning by hue alone
- 1.4.11 Non-text Contrast - 3:1 for graphical objects and UI components
- 1.4.13 Content on Hover or Focus - dismissible, hoverable, persistent tooltips
- 2.1.1 Keyboard - all functionality without a pointer
- 2.4.7 Focus Visible and 2.4.11 Focus Not Obscured (Minimum) - focus must be visible and not hidden behind a sticky header or an overlapping tooltip, a common dashboard failure
- 2.5.3 Label in Name - for icon-only controls, the accessible name must contain the visible label text
- 4.1.2 Name, Role, Value - every custom control must expose all three
The 2.5.3 trap deserves a note. An icon button whose visible tooltip reads "Download CSV" but whose aria-label reads "Export" fails, because a speech-input user saying "click Download CSV" gets nothing. Make the accessible name contain the visible text.
Live and updating dashboards
Real-time dashboards create problems that static charts do not.
A chart refreshing every few seconds is hostile to screen reader users, whose reading is interrupted, and to users with cognitive disabilities, for whom the ground keeps moving. Provide a pause control or a manual refresh, and default to a slower cadence than the engineering team's instinct.
Use aria-live sparingly. Announcing every tick is worse than announcing nothing. Announce meaningful state changes, such as a filter being applied or new data being loaded, in a polite region, and leave routine updates silent.
Animated transitions between chart states also affect users with motion sensitivity. Honour prefers-reduced-motion on chart animation as you would anywhere else.
Tooling: what to check before you commit
Some libraries ship real accessibility modules. Highcharts and ApexCharts are commonly cited for built-in support, and the UK Office for National Statistics chart library was designed with accessibility as a first-class concern. Mainstream BI platforms vary considerably, and their exported and embedded views are frequently much weaker than their authoring interfaces - which matters, because the embed is what your customers get.
No tool is compliant on your behalf. Evaluate one like this:
- Test the embed, not the marketing demo
- Unplug the mouse and try to reach every control in the rendered output
- Check what the export or print view produces, and whether the alternative representation survives it
- Ask the vendor for an accessibility conformance report, and read whether the claims cover the rendered output or only the authoring UI
- Check whether the library lets you supply your own text alternative and data table, or whether it generates one you cannot control
Where this sits in EAA compliance
Under the European Accessibility Act, in-scope services must meet the essential accessibility requirements, with EN 301 549 as the technical route and WCAG 2.1 AA as the practical floor. EN 301 549 v4.1.1, adopted on 24 August 2026, aligns clauses 9 to 11 with WCAG 2.2, with an Official Journal citation expected around October 2026.
One scoping point teams get wrong: customer-facing analytics inside a banking, e-commerce or transport service is part of that service. A spending breakdown in a banking app, a seller dashboard in a marketplace, a punctuality chart on a transport operator's site - these are not exempt internal tools. They are the service.
A testing routine
Five checks, none of which needs a specialist:
- View it in greyscale. If you cannot tell the series apart, hue is doing work it should not.
- Unplug the mouse. Reach every control. Watch for focus disappearing behind sticky headers.
- Turn on a screen reader and try to answer two questions: what is the highest value, and what is the trend. If you cannot, the alternative representation is missing or inadequate.
- Zoom to 400% and check reflow, and that no information is lost or requires two-dimensional scrolling.
- Hand a colleague only the text alternative and ask what the chart shows. If their answer differs from the chart's actual message, rewrite it.
For an existing dashboard estate, remediate in this order: text summary first, because it is cheap and helps everyone; then data table alternatives on the charts users take exact figures from; then colour redundancy; then keyboard and tooltip behaviour; and only then data-point-level navigation, if at all.
The first two steps will move more users across the line than the last one ever will.
Related reading

EAA CE Marking and the Product Compliance Machine Most Digital Teams Have Never Seen
CE marking, EU declarations of conformity, Annex IV technical files: the EAA's product-side compliance regime is nothing like an accessibility statement. Here is what every economic operator needs to know.

Keyboard Accessibility and Focus Order Under WCAG 2.2: A Practical Guide for Front-End and QA Teams
WCAG 2.2 tightened keyboard and focus requirements. Here's what front-end and QA teams need to know about focus order, keyboard traps, JS component failures, manual testing, and EAA/EN 301 549 obligations.

Germany's BFSG at One Year: What the First Wave of Enforcement Means for Every EU-Facing Business
One year after Germany's BFSG took effect, warning letters are circulating, the MLBF is auditing, and the Abmahnung mechanism means enforcement can reach you before any regulator does. Here's what that means in practice.