> ## 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.

# Accessibility

> Make your charts accessible to all users

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:

```jsx theme={null}
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:

```jsx theme={null}
<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"`:

```jsx theme={null}
<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:

```jsx theme={null}
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):

```jsx theme={null}
{/* ❌ 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:

```jsx theme={null}
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:

```jsx theme={null}
// 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>
```

## Tooltips and interaction

### Keyboard-accessible tooltips

Recharts tooltips are keyboard accessible by default. Ensure custom tooltips maintain this:

```jsx theme={null}
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:

```jsx theme={null}
<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:

```jsx theme={null}
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:

```jsx theme={null}
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:

```jsx theme={null}
<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>
```

### Format tick labels

Make tick values readable:

```jsx theme={null}
<YAxis
  tickFormatter={(value) => `$${value.toLocaleString()}`}
/>

<XAxis
  dataKey="date"
  tickFormatter={(value) => new Date(value).toLocaleDateString()}
/>
```

## Legend accessibility

### Ensure legends are readable

```jsx theme={null}
<Legend
  wrapperStyle={{
    fontSize: '14px',
    color: '#333',
  }}
  iconSize={18}
/>
```

### Provide context in legend labels

```jsx theme={null}
<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

```jsx theme={null}
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:

```jsx theme={null}
<XAxis
  tick={{ fontSize: '0.875rem' }}  {/* Instead of 14 */}
/>
```

## Testing accessibility

### Screen reader testing

1. Test with NVDA (Windows), JAWS (Windows), or VoiceOver (macOS)
2. Navigate using keyboard only (Tab, Arrow keys)
3. Verify all information is announced

### Automated testing

Use tools like:

* [axe DevTools](https://www.deque.com/axe/devtools/)
* [Lighthouse](https://developers.google.com/web/tools/lighthouse)
* [WAVE](https://wave.webaim.org/)

### Manual checks

* [ ] Can you navigate to all interactive elements with keyboard?
* [ ] Are focus indicators visible?
* [ ] Do tooltips work without a mouse?
* [ ] Is color contrast sufficient?
* [ ] Are animations respectful of motion preferences?
* [ ] Is there alternative text representation?

## ARIA attributes reference

### Essential ARIA attributes for charts

```jsx theme={null}
<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

<Tip>
  **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
</Tip>

<Warning>
  **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
</Warning>

<Note>
  **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.
</Note>

## Resources

* [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)
* [Accessible SVG Charts](https://www.smashingmagazine.com/2022/06/accessible-svg-charts/)
* [Color Contrast Checker](https://webaim.org/resources/contrastchecker/)
* [ColorBrewer (accessible palettes)](https://colorbrewer2.org/)
