# Marquee

A CSS-driven infinite scroller that repeats its children horizontally or vertically, with optional reverse direction and pause on hover.

- Category: Data Display
- License: MIT
- Page: https://www.saasuji.com/components/marquee
- Install: npx shadcn@latest add https://www.saasuji.com/r/marquee.json

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| children | `React.ReactNode` | — | Items to scroll; required. |
| reverse | `boolean` | `false` | Reverses the animation direction. |
| pauseOnHover | `boolean` | `false` | Pauses the animation while the pointer is over the marquee. |
| vertical | `boolean` | `false` | Animates vertically in a column instead of horizontally in a row. |
| repeat | `number` | `4` | Number of times the children are repeated for a seamless loop. |
| className | `string` | — | Additional classes merged onto the marquee; also set --duration and --gap custom properties here. |
| ...props | `React.ComponentPropsWithoutRef<"div">` | — | All remaining native div attributes are forwarded (id, style, aria-*, …). |

## Source

```tsx
import { type ComponentPropsWithoutRef } from "react"

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

interface MarqueeProps extends ComponentPropsWithoutRef<"div"> {
  /**
   * Optional CSS class name to apply custom styles
   */
  className?: string
  /**
   * Whether to reverse the animation direction
   * @default false
   */
  reverse?: boolean
  /**
   * Whether to pause the animation on hover
   * @default false
   */
  pauseOnHover?: boolean
  /**
   * Content to be displayed in the marquee
   */
  children: React.ReactNode
  /**
   * Whether to animate vertically instead of horizontally
   * @default false
   */
  vertical?: boolean
  /**
   * Number of times to repeat the content
   * @default 4
   */
  repeat?: number
}

export function Marquee({
  className,
  reverse = false,
  pauseOnHover = false,
  children,
  vertical = false,
  repeat = 4,
  ...props
}: MarqueeProps) {
  return (
    <div
      {...props}
      className={cn(
        "group flex gap-(--gap) overflow-hidden p-2 [--duration:40s] [--gap:1rem]",
        {
          "flex-row": !vertical,
          "flex-col": vertical,
        },
        className
      )}
    >
      {Array(repeat)
        .fill(0)
        .map((_, i) => (
          <div
            key={i}
            className={cn("flex shrink-0 justify-around gap-(--gap)", {
              "animate-marquee flex-row": !vertical,
              "animate-marquee-vertical flex-col": vertical,
              "group-hover:[animation-play-state:paused]": pauseOnHover,
              "[animation-direction:reverse]": reverse,
            })}
          >
            {children}
          </div>
        ))}
    </div>
  )
}

```
