View fulldotdev/ui on GitHub

Marquee

A continuously scrolling row of content, with a pause control and a static fallback.

Installation

npx shadcn@latest add @fulldev/marquee

Usage

import {
  Marquee,
  MarqueeContent,
  MarqueeItem,
  MarqueeToggle,
} from "@/components/ui/marquee"
<Marquee class="w-full">
  <MarqueeToggle playLabel="Play" pauseLabel="Pause" />
  <MarqueeContent>
    <MarqueeItem>Design systems</MarqueeItem>
    <MarqueeItem>Astro</MarqueeItem>
    <MarqueeItem>Content sites</MarqueeItem>
  </MarqueeContent>
</Marquee>

Each item renders once. The row loops by moving its own items with Embla and its Auto Scroll plugin, so links and other content are never duplicated.

The row only moves when it can loop and the visitor allows motion. It stays a static, horizontally scrollable row when:

  • the items do not fill the row,
  • the visitor prefers reduced motion,
  • the marquee has no enabled, visible MarqueeToggle, because moving content needs a way to pause it. A row that moves stops when its toggle is later disabled, made inert or hidden,
  • JavaScript has not run.

MarqueeToggle shows only while the row moves. Its labels come from you, so they can be in the page language. Focus inside the row, dragging it or pressing the toggle pauses the motion until the toggle plays it again. Hovering with a mouse pauses it while the pointer is over the marquee.

Examples

Rows

A marquee can hold several MarqueeContent rows. One toggle controls all of them. Set reverse to move a row against the reading direction.

Few items

Items that fit the row stay centered and do not move.

Styling

Items are --spacing(4) apart. Set --marquee-gap on the marquee to change that, for example class="[--marquee-gap:--spacing(12)]".

API Reference

See the GitHub source code for more information on props.