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

# Responsive design

> Build charts that adapt to any screen size and container

Recharts provides powerful tools for creating responsive visualizations that adapt to different screen sizes and container dimensions. The `ResponsiveContainer` component is the foundation of responsive chart design.

## ResponsiveContainer

The `ResponsiveContainer` component automatically adjusts chart dimensions based on its parent container size.

### Basic usage

```tsx theme={null}
import { ResponsiveContainer, LineChart, Line, XAxis, YAxis } from 'recharts';

function ResponsiveChart() {
  return (
    <div style={{ width: '100%', height: 400 }}>
      <ResponsiveContainer>
        <LineChart data={data}>
          <XAxis dataKey="name" />
          <YAxis />
          <Line dataKey="value" stroke="#8884d8" />
        </LineChart>
      </ResponsiveContainer>
    </div>
  );
}
```

<Note>
  The parent container of `ResponsiveContainer` must have a defined width and height. ResponsiveContainer fills 100% of its parent by default.
</Note>

### How it works

The `ResponsiveContainer` component:

1. Observes its parent container using the ResizeObserver API
2. Calculates appropriate dimensions based on container size
3. Provides these dimensions to child charts via React context
4. Re-renders charts when container size changes

```tsx theme={null}
// From src/component/ResponsiveContainer.tsx:170-199
useEffect(() => {
  if (containerRef.current == null || typeof ResizeObserver === 'undefined') {
    return noop;
  }
  let callback = (entries: ResizeObserverEntry[]) => {
    const entry = entries[0];
    if (entry == null) {
      return;
    }
    const { width: containerWidth, height: containerHeight } = entry.contentRect;
    setContainerSize(containerWidth, containerHeight);
    onResizeRef.current?.(containerWidth, containerHeight);
  };
  if (debounce > 0) {
    callback = throttle(callback, debounce, {
      trailing: true,
      leading: false,
    });
  }
  const observer = new ResizeObserver(callback);

  const { width: containerWidth, height: containerHeight } = containerRef.current.getBoundingClientRect();
  setContainerSize(containerWidth, containerHeight);

  observer.observe(containerRef.current);

  return () => {
    observer.disconnect();
  };
}, [setContainerSize, debounce]);
```

## Container dimensions

### Percentage dimensions

Use percentage values for fluid layouts:

```tsx theme={null}
<ResponsiveContainer width="100%" height="100%">
  <LineChart data={data}>
    <Line dataKey="value" stroke="#8884d8" />
  </LineChart>
</ResponsiveContainer>
```

### Fixed dimensions

Use pixel values for fixed-size charts:

```tsx theme={null}
<ResponsiveContainer width={600} height={300}>
  <LineChart data={data}>
    <Line dataKey="value" stroke="#8884d8" />
  </LineChart>
</ResponsiveContainer>
```

### Mixed dimensions

Combine percentage and fixed values:

```tsx theme={null}
<ResponsiveContainer width="100%" height={400}>
  <LineChart data={data}>
    <Line dataKey="value" stroke="#8884d8" />
  </LineChart>
</ResponsiveContainer>
```

## Aspect ratio

Maintain a specific width-to-height ratio:

```tsx theme={null}
<ResponsiveContainer width="100%" aspect={16 / 9}>
  <LineChart data={data}>
    <Line dataKey="value" stroke="#8884d8" />
  </LineChart>
</ResponsiveContainer>
```

<Tabs>
  <Tab title="16:9 (Widescreen)">
    ```tsx theme={null}
    <ResponsiveContainer width="100%" aspect={16/9}>
      <LineChart data={data}>
        <Line dataKey="value" stroke="#8884d8" />
      </LineChart>
    </ResponsiveContainer>
    ```
  </Tab>

  <Tab title="4:3 (Standard)">
    ```tsx theme={null}
    <ResponsiveContainer width="100%" aspect={4/3}>
      <LineChart data={data}>
        <Line dataKey="value" stroke="#8884d8" />
      </LineChart>
    </ResponsiveContainer>
    ```
  </Tab>

  <Tab title="1:1 (Square)">
    ```tsx theme={null}
    <ResponsiveContainer width="100%" aspect={1}>
      <PieChart data={data}>
        <Pie dataKey="value" />
      </PieChart>
    </ResponsiveContainer>
    ```
  </Tab>
</Tabs>

<Info>
  When using `aspect`, the height is calculated as `width / aspect`. This is useful for maintaining visual consistency across different screen sizes.
</Info>

## Minimum and maximum dimensions

Set constraints on chart size:

```tsx theme={null}
<ResponsiveContainer 
  width="100%" 
  height="100%"
  minWidth={300}
  minHeight={200}
  maxHeight={600}
>
  <LineChart data={data}>
    <Line dataKey="value" stroke="#8884d8" />
  </LineChart>
</ResponsiveContainer>
```

## Debouncing resize events

Optimize performance during rapid resize events:

```tsx theme={null}
<ResponsiveContainer 
  width="100%" 
  height={400}
  debounce={200}  // Wait 200ms after resize before re-rendering
>
  <LineChart data={data}>
    <Line dataKey="value" stroke="#8884d8" />
  </LineChart>
</ResponsiveContainer>
```

<Note>
  Debouncing is useful when charts contain large datasets or complex rendering. It prevents excessive re-renders during window resizing.
</Note>

## Resize callback

Execute code when chart size changes:

```tsx theme={null}
import { useState } from 'react';
import { ResponsiveContainer, LineChart, Line } from 'recharts';

function ChartWithResizeTracking() {
  const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
  
  return (
    <div>
      <p>Chart size: {dimensions.width}px × {dimensions.height}px</p>
      <ResponsiveContainer 
        width="100%" 
        height={400}
        onResize={(width, height) => {
          setDimensions({ width, height });
          console.log('Chart resized to:', width, height);
        }}
      >
        <LineChart data={data}>
          <Line dataKey="value" stroke="#8884d8" />
        </LineChart>
      </ResponsiveContainer>
    </div>
  );
}
```

## Responsive patterns

### Full-width charts

```tsx theme={null}
function FullWidthChart() {
  return (
    <div style={{ width: '100%', height: 400 }}>
      <ResponsiveContainer>
        <LineChart data={data}>
          <XAxis dataKey="name" />
          <YAxis />
          <Line dataKey="value" stroke="#8884d8" />
        </LineChart>
      </ResponsiveContainer>
    </div>
  );
}
```

### Dashboard grid

```tsx theme={null}
function DashboardGrid() {
  return (
    <div style={{ 
      display: 'grid', 
      gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
      gap: 20,
    }}>
      <div style={{ height: 300 }}>
        <ResponsiveContainer>
          <LineChart data={data1}>
            <Line dataKey="value" stroke="#8884d8" />
          </LineChart>
        </ResponsiveContainer>
      </div>
      
      <div style={{ height: 300 }}>
        <ResponsiveContainer>
          <BarChart data={data2}>
            <Bar dataKey="value" fill="#82ca9d" />
          </BarChart>
        </ResponsiveContainer>
      </div>
      
      <div style={{ height: 300 }}>
        <ResponsiveContainer>
          <PieChart>
            <Pie data={data3} dataKey="value" />
          </PieChart>
        </ResponsiveContainer>
      </div>
    </div>
  );
}
```

### Mobile-first design

```tsx theme={null}
import { useState, useEffect } from 'react';
import { ResponsiveContainer, LineChart, Line, XAxis, YAxis } from 'recharts';

function MobileFirstChart() {
  const [isMobile, setIsMobile] = useState(false);
  
  useEffect(() => {
    const checkMobile = () => setIsMobile(window.innerWidth < 768);
    checkMobile();
    window.addEventListener('resize', checkMobile);
    return () => window.removeEventListener('resize', checkMobile);
  }, []);
  
  return (
    <div style={{ width: '100%', height: isMobile ? 250 : 400 }}>
      <ResponsiveContainer>
        <LineChart 
          data={data}
          margin={isMobile 
            ? { top: 5, right: 5, left: 0, bottom: 5 }
            : { top: 20, right: 30, left: 20, bottom: 5 }
          }
        >
          <XAxis 
            dataKey="name" 
            tick={{ fontSize: isMobile ? 10 : 12 }}
            angle={isMobile ? -45 : 0}
            textAnchor={isMobile ? 'end' : 'middle'}
          />
          <YAxis tick={{ fontSize: isMobile ? 10 : 12 }} />
          <Line dataKey="value" stroke="#8884d8" strokeWidth={isMobile ? 1 : 2} />
        </LineChart>
      </ResponsiveContainer>
    </div>
  );
}
```

## Breakpoint-based configuration

```tsx theme={null}
import { useState, useEffect } from 'react';
import { ResponsiveContainer, BarChart, Bar, XAxis, YAxis, Legend, Tooltip } from 'recharts';

function BreakpointChart() {
  const [breakpoint, setBreakpoint] = useState('large');
  
  useEffect(() => {
    const updateBreakpoint = () => {
      const width = window.innerWidth;
      if (width < 640) setBreakpoint('small');
      else if (width < 1024) setBreakpoint('medium');
      else setBreakpoint('large');
    };
    
    updateBreakpoint();
    window.addEventListener('resize', updateBreakpoint);
    return () => window.removeEventListener('resize', updateBreakpoint);
  }, []);
  
  const config = {
    small: {
      height: 200,
      layout: 'vertical',
      margin: { top: 5, right: 5, left: 40, bottom: 5 },
      showLegend: false,
    },
    medium: {
      height: 300,
      layout: 'horizontal',
      margin: { top: 20, right: 20, left: 20, bottom: 20 },
      showLegend: true,
    },
    large: {
      height: 400,
      layout: 'horizontal',
      margin: { top: 20, right: 30, left: 20, bottom: 5 },
      showLegend: true,
    },
  }[breakpoint];
  
  return (
    <div style={{ width: '100%', height: config.height }}>
      <ResponsiveContainer>
        <BarChart 
          data={data} 
          layout={config.layout}
          margin={config.margin}
        >
          {config.layout === 'horizontal' ? (
            <>
              <XAxis dataKey="name" />
              <YAxis />
            </>
          ) : (
            <>
              <XAxis type="number" />
              <YAxis dataKey="name" type="category" />
            </>
          )}
          <Tooltip />
          {config.showLegend && <Legend />}
          <Bar dataKey="value" fill="#8884d8" />
        </BarChart>
      </ResponsiveContainer>
    </div>
  );
}
```

## Container queries (CSS)

Leverage modern CSS container queries with ResponsiveContainer:

```tsx theme={null}
// styles.css
.chart-container {
  container-type: size;
  width: 100%;
  height: 400px;
}

@container (max-width: 600px) {
  .chart-wrapper {
    height: 250px;
  }
}

@container (min-width: 601px) {
  .chart-wrapper {
    height: 400px;
  }
}

// Component
function ContainerQueryChart() {
  return (
    <div className="chart-container">
      <div className="chart-wrapper">
        <ResponsiveContainer>
          <LineChart data={data}>
            <Line dataKey="value" stroke="#8884d8" />
          </LineChart>
        </ResponsiveContainer>
      </div>
    </div>
  );
}
```

## Performance considerations

### Optimize large datasets

```tsx theme={null}
import { useMemo } from 'react';
import { ResponsiveContainer, LineChart, Line } from 'recharts';

function OptimizedChart({ rawData }) {
  // Downsample data on large screens, more aggressive on mobile
  const processedData = useMemo(() => {
    const isMobile = window.innerWidth < 768;
    const sampleRate = isMobile ? 10 : 5;
    return rawData.filter((_, index) => index % sampleRate === 0);
  }, [rawData]);
  
  return (
    <ResponsiveContainer width="100%" height={400}>
      <LineChart data={processedData}>
        <Line 
          dataKey="value" 
          stroke="#8884d8"
          isAnimationActive={false}  // Disable animation for better performance
          dot={false}  // Hide dots on mobile for performance
        />
      </LineChart>
    </ResponsiveContainer>
  );
}
```

### Lazy loading charts

```tsx theme={null}
import { lazy, Suspense } from 'react';

const Chart = lazy(() => import('./Chart'));

function LazyChart() {
  return (
    <Suspense fallback={<div>Loading chart...</div>}>
      <Chart data={data} />
    </Suspense>
  );
}
```

## Common issues

<Accordion title="Chart not rendering">
  Ensure the parent container has explicit dimensions:

  ```tsx theme={null}
  // Wrong - no height defined
  <div>
    <ResponsiveContainer>
      <LineChart data={data} />
    </ResponsiveContainer>
  </div>

  // Correct - explicit height
  <div style={{ height: 400 }}>
    <ResponsiveContainer>
      <LineChart data={data} />
    </ResponsiveContainer>
  </div>
  ```
</Accordion>

<Accordion title="Chart flashing on resize">
  Add debounce to reduce re-renders:

  ```tsx theme={null}
  <ResponsiveContainer debounce={100}>
    <LineChart data={data} />
  </ResponsiveContainer>
  ```
</Accordion>

<Accordion title="Chart too small on mobile">
  Set minimum dimensions:

  ```tsx theme={null}
  <ResponsiveContainer 
    width="100%" 
    height={400}
    minHeight={250}
  >
    <LineChart data={data} />
  </ResponsiveContainer>
  ```
</Accordion>

<Accordion title="Legend overlapping chart">
  Adjust chart margins based on legend position:

  ```tsx theme={null}
  <LineChart 
    margin={{ top: 5, right: 20, bottom: 40, left: 20 }}
  >
    <Legend verticalAlign="bottom" height={36} />
  </LineChart>
  ```
</Accordion>
