# Loader Bars Equalizer — React Loader Component

> Rounded bars bounce at different tempos like an audio meter; grows from the baseline or mirrors around the centre line.

- Category: [Loaders](https://pixelpapa.com/components/loaders.md)
- Tags: loader, bars, equalizer, audio, loading
- Dependencies: none (plus React and Tailwind CSS v4)
- Last updated: 2026-11-13
- Live preview: https://pixelpapa.com/components/loaders/loader-bars-equalizer

## Install

```bash
npx shadcn@latest add "https://pixelpapa.com/r/loader-bars-equalizer.json"
```

The file is written to `components/pixelpapa/loader-bars-equalizer.tsx`. To install manually, copy the source below into your project. It imports `cn` from `@/lib/utils`, which every shadcn project has.

## Source

```tsx
"use client";

import { cn } from "@/lib/utils";

type LoaderBarsEqualizerProps = {
  /** Number of bars. */
  bars?: number;
  /** Height in px; width follows from the bar count. */
  size?: number;
  /** Grow from the bottom, or mirror around the middle. */
  variant?: "baseline" | "center";
  /** Tempo multiplier; 2 is twice as fast. */
  tempo?: number;
  /** Accessible label. */
  label?: string;
  className?: string;
};

// Three different rhythms; bars cycle through them with different durations so the pattern rarely repeats.
const rhythms = ["pp-loader-bars-equalizer-a", "pp-loader-bars-equalizer-b", "pp-loader-bars-equalizer-c"];

export function LoaderBarsEqualizer({
  bars = 5,
  size = 40,
  variant = "baseline",
  tempo = 1,
  label = "Loading",
  className,
}: LoaderBarsEqualizerProps) {
  const width = Math.max(2, size * 0.14);

  return (
    <span
      role="status"
      aria-label={label}
      className={cn(
        "inline-flex shrink-0 text-primary",
        variant === "baseline" ? "items-end" : "items-center",
        className,
      )}
      style={{ height: size, gap: width * 0.7 }}
    >
      <style>{`
        @keyframes pp-loader-bars-equalizer-a { 0%, 100% { transform: scaleY(0.25); } 30% { transform: scaleY(1); } 60% { transform: scaleY(0.5); } 80% { transform: scaleY(0.8); } }
        @keyframes pp-loader-bars-equalizer-b { 0%, 100% { transform: scaleY(0.7); } 25% { transform: scaleY(0.3); } 55% { transform: scaleY(1); } 75% { transform: scaleY(0.45); } }
        @keyframes pp-loader-bars-equalizer-c { 0%, 100% { transform: scaleY(0.45); } 20% { transform: scaleY(0.9); } 50% { transform: scaleY(0.2); } 70% { transform: scaleY(0.65); } }
        @media (prefers-reduced-motion: reduce) {
          .pp-loader-bars-equalizer-bar { animation-duration: 4s !important; }
        }
      `}</style>
      {Array.from({ length: bars }, (_, i) => (
        <span
          key={i}
          className={cn(
            "pp-loader-bars-equalizer-bar h-full rounded-full bg-current will-change-transform",
            variant === "baseline" ? "origin-bottom" : "origin-center",
          )}
          style={{
            width,
            transform: "scaleY(0.5)",
            animation: `${rhythms[i % 3]} ${(0.9 + ((i * 3) % 4) * 0.17) / tempo}s ease-in-out ${-i * 0.23}s infinite`,
          }}
        />
      ))}
    </span>
  );
}

export default function LoaderBarsEqualizerDemo() {
  return (
    <div className="flex w-full max-w-xl flex-col gap-4">
      <div className="grid grid-cols-3 gap-4">
        {[
          { label: "Baseline", node: <LoaderBarsEqualizer /> },
          { label: "Centered", node: <LoaderBarsEqualizer variant="center" bars={7} className="text-chart-3" /> },
          { label: "Dense", node: <LoaderBarsEqualizer bars={12} size={56} tempo={1.4} className="text-chart-2" /> },
        ].map((v) => (
          <div
            key={v.label}
            className="flex flex-col items-center rounded-2xl border border-border bg-card px-4 pt-8 pb-5 shadow-sm"
          >
            <div className="flex h-16 items-center justify-center">{v.node}</div>
            <p className="mt-4 text-sm font-medium text-card-foreground">{v.label}</p>
          </div>
        ))}
      </div>
      <div className="flex items-center gap-4 rounded-2xl border border-border bg-card p-4 shadow-sm">
        <div className="flex size-12 shrink-0 items-center justify-center rounded-xl bg-primary/10">
          <LoaderBarsEqualizer bars={4} size={20} label="Now playing" />
        </div>
        <div className="min-w-0 flex-1">
          <p className="truncate text-sm font-medium text-card-foreground">Low Tide, Slow Morning</p>
          <p className="truncate text-xs text-muted-foreground">Harbour Lights · buffering next track</p>
        </div>
        <span className="font-mono text-xs text-muted-foreground tabular-nums">2:41</span>
      </div>
    </div>
  );
}
```

## AI prompt

```text
Add the "Loader Bars Equalizer" component from PixelPapa UI to this project.

What it is: Rounded bars bounce at different tempos like an audio meter; grows from the baseline or mirrors around the centre line.
Category: Loaders. Depends on: no extra packages.

1. Install it with the shadcn CLI:
   npx shadcn@latest add "https://pixelpapa.com/r/loader-bars-equalizer.json"
   (If the CLI is unavailable, fetch that URL, write files[0].content to components/pixelpapa/loader-bars-equalizer.tsx and install the listed dependencies.)
2. Import it from "@/components/pixelpapa/loader-bars-equalizer" and place it where I describe below.
3. Keep its animation timings and accessibility attributes. Replace the demo copy and data with content that fits my product, and use my existing theme tokens (bg-background, text-foreground, bg-primary, border-border) rather than hard-coded colours.

Where to use it: <describe the page and position here>
```

## More loaders

- [Loader Infinity Path](https://pixelpapa.com/components/loaders/loader-infinity-path.md) (Pro): A comet of stroke dashes laps an SVG infinity loop, its tail built from stacked dashes that thin out behind the head.
- [Loader Morphing Shape](https://pixelpapa.com/components/loaders/loader-morphing-shape.md): A single shape turns a quarter at a time while its corners melt between square, circle, leaf and diamond, trailed by a lagging ghost.
- [Loader Orbit Dots](https://pixelpapa.com/components/loaders/loader-orbit-dots.md): Dots chase each other around a ring, bunching at the top and fanning out as they fall, around a softly pulsing core.
- [Loader Progress Ring Percent](https://pixelpapa.com/components/loaders/loader-progress-ring-percent.md) (Pro): A ring that springs to its value while the percentage counts along inside it, then swaps to a check mark when it reaches 100.
- [Loader Skeleton Card](https://pixelpapa.com/components/loaders/loader-skeleton-card.md) (Pro): Skeleton blocks for a card and a list, swept by one shared diagonal shimmer per surface so every block glints in sync.
- [Loader Stepped Progress](https://pixelpapa.com/components/loaders/loader-stepped-progress.md) (Pro): A multi-step progress track: connectors fill, the active step spins, finished steps pop a check, and the status line rolls to the next message.
