Documentation Index
Fetch the complete documentation index at: https://mintlify.com/recharts/recharts/llms.txt
Use this file to discover all available pages before exploring further.
Accessible charts ensure that all users, including those using assistive technologies, can understand your data. This guide covers accessibility best practices for Recharts.
Semantic structure
Provide descriptive titles
Always add a title that describes what the chart shows:
function AccessibleChart() {
return (
<div>
<h2 id="chart-title">Monthly Revenue 2024</h2>
<LineChart
width={600}
height={300}
data={data}
aria-labelledby="chart-title"
>
<XAxis dataKey="month" />
<YAxis />
<Line dataKey="revenue" stroke="#8884d8" />
</LineChart>
</div>
);
}
Add descriptive labels
Use ARIA labels for context:
<LineChart
width={600}
height={300}
data={data}
aria-label="Line chart showing monthly revenue from January to December 2024"
role="img"
>
{/* ... */}
</LineChart>
Animation accessibility
Respect motion preferences
Recharts automatically respects the user’s prefers-reduced-motion setting when using isAnimationActive="auto":
<Line
dataKey="value"
isAnimationActive="auto" {/* Respects prefers-reduced-motion */}
/>
This is the recommended approach for all animations.
Provide animation controls
For critical visualizations, offer users control:
function AccessibleAnimatedChart() {
const [animate, setAnimate] = useState(true);
return (
<div>
<button onClick={() => setAnimate(!animate)}>
{animate ? 'Disable' : 'Enable'} Animations
</button>
<LineChart width={600} height={300} data={data}>
<Line
dataKey="value"
isAnimationActive={animate}
/>
</LineChart>
</div>
);
}
Color and contrast
Ensure sufficient contrast
Use colors with WCAG AA compliant contrast ratios (at least 4.5:1 for text, 3:1 for UI components):
{/* ❌ Low contrast */}
<Line dataKey="value" stroke="#ccc" />
{/* ✅ Good contrast */}
<Line dataKey="value" stroke="#0066cc" />
Don’t rely on color alone
Use patterns, shapes, or labels in addition to color:
function AccessibleMultiSeriesChart() {
return (
<LineChart width={600} height={300} data={data}>
<XAxis dataKey="month" />
<YAxis />
<Legend />
{/* Different stroke styles */}
<Line
dataKey="revenue"
stroke="#8884d8"
strokeWidth={2}
name="Revenue"
/>
<Line
dataKey="profit"
stroke="#82ca9d"
strokeDasharray="5 5"
strokeWidth={2}
name="Profit"
/>
<Line
dataKey="cost"
stroke="#ffc658"
strokeDasharray="3 3"
strokeWidth={2}
name="Cost"
/>
</LineChart>
);
}
Use accessible color palettes
Choose colorblind-friendly palettes:
// Example: Colorblind-safe palette
const colors = {
blue: '#0173B2',
orange: '#DE8F05',
green: '#029E73',
red: '#CC78BC',
purple: '#CA9161',
};
<BarChart data={data}>
<Bar dataKey="category1" fill={colors.blue} />
<Bar dataKey="category2" fill={colors.orange} />
<Bar dataKey="category3" fill={colors.green} />
</BarChart>
Recharts tooltips are keyboard accessible by default. Ensure custom tooltips maintain this:
const AccessibleTooltip = ({ active, payload, label }) => {
if (!active || !payload) return null;
return (
<div
style={{
backgroundColor: 'white',
padding: '12px',
border: '1px solid #ccc',
}}
role="tooltip"
aria-live="polite"
>
<p style={{ margin: 0, fontWeight: 'bold' }}>{label}</p>
{payload.map((entry, index) => (
<p key={index} style={{ margin: 0, color: entry.color }}>
{entry.name}: {entry.value}
</p>
))}
</div>
);
};
<Tooltip content={<AccessibleTooltip />} />
Focus indicators
Ensure interactive elements have visible focus states:
<LineChart data={data}>
<Line
dataKey="value"
stroke="#8884d8"
activeDot={{
r: 8,
stroke: '#0066cc',
strokeWidth: 2,
fill: 'white',
}}
/>
</LineChart>
Alternative text representations
Provide data tables
Offer a table version for screen reader users:
function ChartWithTable({ data }) {
const [showTable, setShowTable] = useState(false);
return (
<div>
<button onClick={() => setShowTable(!showTable)}>
{showTable ? 'Show Chart' : 'Show Data Table'}
</button>
{showTable ? (
<table>
<caption>Monthly Revenue Data</caption>
<thead>
<tr>
<th>Month</th>
<th>Revenue</th>
</tr>
</thead>
<tbody>
{data.map((item, index) => (
<tr key={index}>
<td>{item.month}</td>
<td>${item.revenue.toLocaleString()}</td>
</tr>
))}
</tbody>
</table>
) : (
<LineChart width={600} height={300} data={data}>
<XAxis dataKey="month" />
<YAxis />
<Line dataKey="revenue" stroke="#8884d8" />
</LineChart>
)}
</div>
);
}
Add text descriptions
Provide a text summary of key insights:
function DescribedChart({ data }) {
const maxRevenue = Math.max(...data.map(d => d.revenue));
const minRevenue = Math.min(...data.map(d => d.revenue));
return (
<div>
<h2>Monthly Revenue</h2>
<p id="chart-description">
This chart shows monthly revenue throughout 2024.
Revenue ranged from ${minRevenue.toLocaleString()} to ${maxRevenue.toLocaleString()}.
</p>
<LineChart
width={600}
height={300}
data={data}
aria-describedby="chart-description"
>
<XAxis dataKey="month" />
<YAxis />
<Line dataKey="revenue" stroke="#8884d8" />
</LineChart>
</div>
);
}
Axis accessibility
Label your axes
Always label axes clearly:
<LineChart width={600} height={300} data={data}>
<XAxis
dataKey="month"
label={{ value: 'Month', position: 'insideBottom', offset: -5 }}
/>
<YAxis
label={{ value: 'Revenue ($)', angle: -90, position: 'insideLeft' }}
/>
<Line dataKey="revenue" stroke="#8884d8" />
</LineChart>
Make tick values readable:
<YAxis
tickFormatter={(value) => `$${value.toLocaleString()}`}
/>
<XAxis
dataKey="date"
tickFormatter={(value) => new Date(value).toLocaleDateString()}
/>
Legend accessibility
Ensure legends are readable
<Legend
wrapperStyle={{
fontSize: '14px',
color: '#333',
}}
iconSize={18}
/>
Provide context in legend labels
<Line
dataKey="revenue"
name="Monthly Revenue (USD)"
stroke="#8884d8"
/>
<Line
dataKey="profit"
name="Net Profit (USD)"
stroke="#82ca9d"
/>
Responsive design
Adapt to different screen sizes
function ResponsiveAccessibleChart() {
const isMobile = window.innerWidth < 768;
return (
<ResponsiveContainer width="100%" height={isMobile ? 300 : 400}>
<LineChart data={data}>
<XAxis
dataKey="month"
angle={isMobile ? -45 : 0}
textAnchor={isMobile ? 'end' : 'middle'}
height={isMobile ? 80 : 30}
/>
<YAxis width={isMobile ? 40 : 60} />
<Tooltip />
<Legend
layout={isMobile ? 'horizontal' : 'vertical'}
align={isMobile ? 'center' : 'right'}
/>
<Line dataKey="value" stroke="#8884d8" />
</LineChart>
</ResponsiveContainer>
);
}
Support text scaling
Use relative units for text:
<XAxis
tick={{ fontSize: '0.875rem' }} {/* Instead of 14 */}
/>
Testing accessibility
Screen reader testing
- Test with NVDA (Windows), JAWS (Windows), or VoiceOver (macOS)
- Navigate using keyboard only (Tab, Arrow keys)
- Verify all information is announced
Automated testing
Use tools like:
Manual checks
ARIA attributes reference
Essential ARIA attributes for charts
<LineChart
width={600}
height={300}
data={data}
role="img"
aria-label="Descriptive label"
aria-labelledby="chart-title" {/* Reference to title element */}
aria-describedby="chart-desc" {/* Reference to description */}
>
{/* ... */}
</LineChart>
Best practices checklist
Core accessibility principles
- ✅ Provide text alternatives (titles, labels, descriptions)
- ✅ Use sufficient color contrast
- ✅ Don’t rely on color alone
- ✅ Make interactive elements keyboard accessible
- ✅ Respect motion preferences
- ✅ Support responsive design and text scaling
- ✅ Test with assistive technologies
Common pitfalls
- ❌ Missing axis labels
- ❌ Low color contrast
- ❌ Forced animations that can’t be disabled
- ❌ No alternative to visual representation
- ❌ Small touch targets on mobile
- ❌ Unlabeled data series
WCAG compliance levels
- Level A: Basic accessibility (minimum)
- Level AA: Recommended for most sites (includes 4.5:1 contrast)
- Level AAA: Enhanced accessibility (includes 7:1 contrast)
Aim for at least WCAG 2.1 Level AA compliance.
Resources