Skip to content
WANCRAFT

C.12Typography & Text

Infinite Marquee

A seamless horizontal marquee that eases to a stop on hover and never jumps.

ReactCSSTailwindintermediate

Overview

Infinite Marquee repeats its items just enough times to cover the viewport and slides the track by exactly one group width with the Web Animations API, so the loop is mathematically seamless at any size. Speed is set in pixels per second, it eases to a stop under the mouse or when keyboard focus enters, pauses offscreen and in background tabs, and keeps its position when options change. Copies are hidden from assistive technology, and reduced-motion users get a static, scrollable row.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/infinite-marquee.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/infinite-marquee.json

Method 02 · Copy and paste

  1. 1. No extra dependencies — React and Tailwind CSS only.
  2. 2. Copy the source from the Code tab into components/ui/infinite-marquee.tsx.
  3. 3. Import it and adjust props.
Dependencies
None
Peer
react ≥ 18, tailwindcss ≥ 4
Added
1 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { InfiniteMarquee } from "@/components/ui/infinite-marquee";

export function InfiniteMarqueeExample() {
  const items = ["Motion", "Typography", "Layout", "Springs", "Canvas", "Accessibility"];

  return (
    <InfiniteMarquee aria-label="Capabilities">
      {items.map((item) => (
        <span key={item} className="rounded-full border px-4 py-2 text-sm">
          {item}
        </span>
      ))}
    </InfiniteMarquee>
  );
}

03Props

PropTypeDefaultDescription
childrenReactNode—Items to scroll. Each child is rendered as one list item.
direction"left" | "right""left"Travel direction.
speednumber48Speed in pixels per second (independent of content width).
gapnumber40Space between items in px, including the seam between copies.
pauseOnHoverbooleantrueEase to a stop while a mouse hovers the marquee.
fadebooleantrueFade the left and right edges with a mask.
controlsbooleanfalseShow a pause / play toggle button.
...propsHTMLAttributes<HTMLDivElement>—Native attributes (aria-label, className, style) are forwarded to the root.

04Features

  • 01Seamless loop: the track moves exactly one measured group width
  • 02Repeats items only as often as needed to fill the container (ResizeObserver)
  • 03Speed in px/s, independent of content length
  • 04Eases to a stop on hover; pauses offscreen and in background tabs
  • 05Keeps its position when speed or direction change
motion · continuousinput · hoverinput · focusinput · viewport

05Accessibility

  • Items are a real list; repeated copies are aria-hidden and inert, so links are announced and focusable once.
  • Movement stops while keyboard focus is inside, and an optional pause button satisfies WCAG 2.2.2.
  • With prefers-reduced-motion it renders a static, keyboard-scrollable row.