Recharts Accessibility
Permalink to "Recharts Accessibility"Recharts is a popular React charting library that renders SVG through declarative components. Its accessibility support is basic but improving: an accessibilityLayer prop on chart containers adds keyboard navigation of data points via the tooltip, with arrow keys moving between points and the tooltip content announced. It does not write descriptions, provide data tables or choose colour-independent styles; those are yours to add around and inside the chart.
This guide belongs to chart library accessibility.
Spec reference
Permalink to "Spec reference"accessibilityLayer— onLineChart,BarChartand others in recent versions; makes the chart focusable and lets arrow keys move the active tooltip; tooltip content is exposed via a live region.- SVG accessibility — the chart
svgcan takerole="img"witharia-label, or be wrapped in afigurewith a caption. - SC 1.1.1 (A) — text alternative; SC 2.1.1 (A) — keyboard; SC 1.4.1 (A) — colour independence.
When to use — and when not to
Permalink to "When to use — and when not to"Recharts suits React dashboards with standard chart types. Turn on accessibilityLayer, wrap every chart in a figure with a heading and summary, and provide a table.
For complex accessibility requirements (sonification, detailed point descriptions, keyboard navigation across many series), consider a library with a deeper accessibility module, or supplement Recharts with your own navigation.
The misapplication: relying on the tooltip as the only place values appear, with tooltips that show only on hover.
Annotated code example
Permalink to "Annotated code example"import { LineChart, Line, XAxis, YAxis, Tooltip, Legend, ResponsiveContainer, LabelList } from 'recharts';
function RevenueChart({ data }) {
const [showTable, setShowTable] = useState(false);
return (
<figure aria-labelledby="rev-h" aria-describedby="rev-sum">
<h3 id="rev-h">Revenue by region, 2026</h3>
<p id="rev-sum">North grew fastest (+18%); South declined in Q3.</p>
<ResponsiveContainer width="100%" height={320}>
<LineChart data={data} accessibilityLayer> {/* keyboard + announced tooltip */}
<XAxis dataKey="quarter" label={{ value: 'Quarter', position: 'insideBottom', offset: -4 }} />
<YAxis label={{ value: 'Revenue (million euros)', angle: -90, position: 'insideLeft' }} />
<Tooltip formatter={(v) => `${v} million euros`} /> {/* units in announcements */}
<Line dataKey="north" name="North" stroke="#155c38" dot={{ r: 4 }}>
<LabelList dataKey="north" position="top" /> {/* direct labels */}
</Line>
<Line dataKey="south" name="South" stroke="#8a6000" strokeDasharray="6 4" dot={{ r: 4, strokeWidth: 2 }} /> {/* dashed: not colour only */}
<Legend />
</LineChart>
</ResponsiveContainer>
<button type="button" aria-expanded={showTable} onClick={() => setShowTable(s => !s)}>
{showTable ? 'Hide' : 'Show'} revenue data table
</button>
{showTable && <RevenueTable data={data} />}
</figure>
);
}
Keyboard & AT behaviour
Permalink to "Keyboard & AT behaviour"| Interaction | Behaviour with accessibilityLayer | Expected announcement |
|---|---|---|
| Tab | Focus the chart | Chart (figure name from context) |
| Right / Left | Move active point | Tooltip content: “Q3, North: 4.6 million euros, South: 2.9 million euros” |
| Tab | Leave the chart | Next control (table toggle) |
| Enter on table toggle | Show table | “Show revenue data table, expanded” |
Integration context
Permalink to "Integration context"Table toggles follow show-as-table toggles for charts. Direct labelling is covered in direct labelling instead of legends, and keyboard models in adding keyboard navigation to SVG line charts.
Gotchas
Permalink to "Gotchas"Version. accessibilityLayer arrived in Recharts 2.x minor releases and its behaviour evolved; check your version and enable it explicitly where it is not the default.
Multiple charts. Several charts each with keyboard focus add tab stops; that is acceptable, but give each figure a heading so users know which chart they are in.
Custom tooltips. If you render a custom tooltip component, make sure its text includes series names and units — it is what gets announced.
Worked example
Permalink to "Worked example"A React product analytics dashboard used eight Recharts charts with colour-only lines and hover tooltips. After enabling accessibilityLayer, adding figure headings and summaries, dashed and dotted line styles, direct end labels, tooltip formatters with units and a “Show data table” toggle per chart, a screen reader user could explore each chart by arrow keys and read the full data in tables. The design team liked the direct labels enough to remove most legends.
A ChartFigure wrapper
Permalink to "A ChartFigure wrapper"function ChartFigure({ title, summary, table, children }) {
const id = useId(); const [open, setOpen] = useState(false);
return (
<figure aria-labelledby={`${id}-t`} aria-describedby={`${id}-s`}>
<h3 id={`${id}-t`}>{title}</h3>
<p id={`${id}-s`}>{summary}</p>
{children} {/* the Recharts chart with accessibilityLayer */}
<button type="button" aria-expanded={open} onClick={() => setOpen(o => !o)}>{open ? 'Hide' : 'Show'} data table</button>
{open && table}
</figure>
);
}
Every Recharts chart in the product goes through this wrapper, so titles, summaries and tables are never forgotten.
Testing it with a screen reader
Permalink to "Testing it with a screen reader"- Navigate to each figure by heading; confirm the summary.
- Tab into the chart; use arrows; confirm tooltip announcements with units and series names.
- View the chart in greyscale; confirm series remain distinguishable.
- Open the table; confirm it matches the chart data.
Common mistakes
Permalink to "Common mistakes"- accessibilityLayer not enabled.
- Unitless tooltip values.
- Colour-only lines.
- No data table.
Adoption checklist for teams
Permalink to "Adoption checklist for teams"- Wrap Recharts charts in a
ChartFigurecomponent with required title and summary. - Enable
accessibilityLayerin a shared chart defaults helper. - Provide series style presets with dashes and markers.
- Include a table toggle in
ChartFigure. - Test each chart type with a screen reader once, then reuse.
FAQ
Permalink to "FAQ"Does Recharts support keyboard navigation?
With accessibilityLayer in recent versions, yes, through tooltip navigation.
Does it add aria-labels to the SVG?
Not meaningful ones by default; name the chart through a surrounding figure and heading.
How do I make bars distinguishable without colour?
Use patterns (SVG pattern fills), direct value labels and clear series names.
Can legends toggle series accessibly?
Recharts legends are not buttons by default; build an HTML toggle group if you need series toggling.
Is Recharts suitable for complex accessibility needs?
For standard dashboards, yes with additions. For extensive keyboard exploration or sonification, consider libraries with deeper support.
How do I handle responsive charts?
ResponsiveContainer resizes the SVG; ensure text remains readable at small sizes and the table remains available.
What about dark mode?
Pass theme-aware colours and verify contrast in both themes.
How do I add patterns to bars in Recharts?
Define SVG pattern elements in a defs block inside the chart and reference them with fill=“url(#pattern-id)” on Bar components; keep a solid outline for contrast.
Does accessibilityLayer work with all chart types?
It is available on the common cartesian charts in recent versions; check pie and radial charts in your version, and fall back to a table and summary where it is missing.
Can I customise what accessibilityLayer announces?
The announcement comes from tooltip content, so a custom Tooltip component or formatter controls it. Include series names and units.
How do I handle charts with many series?
Limit visible series, offer legend toggles as HTML buttons, and keep the table as the complete view.
Related
Permalink to "Related"- Highcharts accessibility module — deeper built-in support
- Show-as-table toggles — data access
- Patterns and shapes for colour-independent charts — series styles