# Marquee

> Endless, seamless scroller for logos and testimonials that glides to a stop on hover.

Component · Pro · https://lodeui.com/components/marquee

## When to use

- Logo walls, testimonials and tag clouds on landing pages.

## When not to use

- Content people must read or act on: moving text is hard to read.
- More than two marquees in one view.

## Installation

```bash
npx shadcn@latest add @lode/marquee
```

Pro: needs a Lode API key and the `@lode` registry in components.json. See https://lodeui.com/docs/cli.

npm dependencies: motion, lucide-react

## Usage

```tsx title="example.tsx"
import { Marquee } from "@/components/ui/marquee";

export function Logos({ names }: { names: string[] }) {
  return (
    <Marquee aria-label="Customers" speed={36}>
      {names.map((n) => <span key={n} className="text-lg font-semibold">{n}</span>)}
    </Marquee>
  );
}
```

## API reference

### Marquee

Duplicates its children and scrolls them endlessly. The duplicate is hidden from screen readers.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| children | `ReactNode` | – | The items, rendered in a row or column. |
| speed | `number` | `40` | Pixels per second. |
| direction | `"left" \| "right" \| "up" \| "down"` | `"left"` | Scroll direction. |
| pauseOnHover | `boolean` | `true` | Glide to a stop while hovered or focused. |
| fade | `boolean` | `true` | Fade content out at the edges. |
| gap | `number` | `16` | Space between items in px. |
| controls | `boolean` | `true` | A pause / play button, shown on hover and focus. |

## Keyboard interactions

| Keys | Action |
| --- | --- |
| Tab | Focus an item or the pause button; scrolling slows to a stop |
| Enter / Space | Pause or play (on the button) |

## Accessibility

- A labelled region; only the first copy is read.
- Pauses on hover and focus, and has a pause button, so moving content can always be stopped.
- Under reduced motion it becomes a static row you can scroll.

## Motion

- Speed eases to zero and back instead of stopping abruptly.
- The loop wraps at exactly one copy's length, so there is no visible jump.

## Responsive behavior

- Fills its container; items keep their natural size.
- Vertical marquees need a height on the container.

## Performance

- One requestAnimationFrame loop writes a transform; no React renders while moving.
- Width is measured with ResizeObserver, so font loading never breaks the loop.

## Notes for AI

- Always pass aria-label.
- Keep items short and visual; put long copy elsewhere.

## Related

- [Orbiting circles](https://lodeui.com/components/orbiting-circles) — Icons orbiting a center on rings, staying upright as they travel.
- [Carousel](https://lodeui.com/components/carousel) — Swipeable slides with arrows, animated dots, keys and pausable autoplay.
- [Animated list](https://lodeui.com/components/animated-list) — A feed where new entries spring in at the top and older ones make room.
