# Marquee

> Infinite horizontal scroller with faded edges that loops any content, runs in either direction and pauses on hover.

- Collection: Components
- Tier: free
- Docs: https://geturui.com/docs/marquee
- Install: `npx shadcn@latest add @geturui/marquee`

## Usage

```tsx
import { Marquee } from "@/components/ui/marquee";

const logos = ["Ledgerline", "Orbit", "Fieldnote", "Quill", "Tidepool"];

export function LogoCloud() {
  return (
    <Marquee duration={30}>
      {logos.map((name) => (
        <span key={name} className="text-lg font-semibold text-ink-muted">
          {name}
        </span>
      ))}
    </Marquee>
  );
}
```

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| children | `ReactNode` | — | Items for one loop. They're duplicated once to make it seamless. |
| duration | `number` | 40 | Seconds per loop; higher is slower. |
| reverse | `boolean` | false | Scroll left to right instead. |
| pauseOnHover | `boolean` | true | Pause while the pointer is over it. |
| className | `string` | — | Classes for the outer track. |

## Accessibility

- The duplicate copy that makes the loop seamless is aria-hidden, so content is announced once.
- Stops completely under prefers-reduced-motion.
- Pauses on hover so people can read a card; avoid putting the only copy of important links inside it.

## Source

### components/ui/marquee.tsx

```tsx
import * as React from "react";
import { cn } from "@/lib/utils";

export interface MarqueeProps {
  children: React.ReactNode;
  /** Seconds per loop. */
  duration?: number;
  reverse?: boolean;
  pauseOnHover?: boolean;
  className?: string;
}

/** Infinite horizontal scroller with faded edges. Pauses on hover; stops under reduced motion. */
export function Marquee({ children, duration = 40, reverse, pauseOnHover = true, className }: MarqueeProps) {
  return (
    <div className={cn("group/marquee fade-x relative overflow-hidden", className)}>
      <div
        className={cn(
          "flex w-max gap-4 animate-marquee motion-reduce:animate-none",
          pauseOnHover && "group-hover/marquee:[animation-play-state:paused]",
        )}
        style={{ ["--marquee-duration" as string]: `${duration}s`, animationDirection: reverse ? "reverse" : undefined }}
      >
        <div className="flex gap-4">{children}</div>
        <div className="flex gap-4" aria-hidden>
          {children}
        </div>
      </div>
    </div>
  );
}

```
