Infinite Ribbon

Looping marquee for banners and dividers—theme-aware, accessible, and seamless on any viewport width.

Installation

npx shadcn@latest add @iconiq/infiniteribbon

File Structure

Usage

"use client";

import { InfiniteRibbon } from "@/components/ui/infiniteribbon";

export function InfiniteRibbonPreview() {
  return (
    <div className="relative h-full min-h-[24rem] w-full overflow-hidden bg-white">
      <div className="absolute top-1/2 left-1/2 z-0 w-[145%] max-w-none -translate-x-1/2 -translate-y-1/2">
        <InfiniteRibbon rotation={5}
      duration={42}
    >
          Build fast, responsive, and beautiful interfaces with ready-to-use components. Designed for developers.
        </InfiniteRibbon>
      </div>
      <div className="absolute top-1/2 left-1/2 z-10 w-[145%] max-w-none -translate-x-1/2 -translate-y-1/2">
        <InfiniteRibbon reverse rotation={-5}
      duration={42}
    >
          Build fast, responsive, and beautiful interfaces with ready-to-use components. Designed for developers.
        </InfiniteRibbon>
      </div>
    </div>
  );
}

Props

Props
Description

InfiniteRibbon

children

Content repeated across the moving ribbon. Short announcement copy works best because it stays legible while scrolling.

Type React.ReactNode

items

Optional list of strings rendered with `separator` between each item instead of a single `children` node.

Type string[]

separator

Divider rendered between `items` entries.

Type React.ReactNode·Default " · "

repeat

Minimum number of copies rendered per half of the seamless track. The component auto-expands this value when the viewport is wider than the measured segment.

Type number·Default 5

duration

Loop duration in seconds for one half of the track. Ignored when `speed` is set. Values below 0.1 are clamped.

Type number·Default 10

speed

Optional scroll speed in pixels per second. When set, loop duration is derived from the measured half-track distance.

Type number

reverse

Runs the marquee from left to right instead of the default right-to-left movement.

Type boolean·Default false

rotation

Degrees applied to an outer wrapper so additional transforms on the root do not conflict with diagonal banner layouts.

Type number·Default 0

variant

Built-in surface tone mapped to Iconiq theme tokens instead of hard-coded colors.

Type "default" | "brand" | "warning"·Default "default"

gap

Spacing between repeated segments.

Type number | string·Default "2rem"

pauseOnHover

Pauses the animation while the ribbon is hovered or contains focused interactive content.

Type boolean·Default true

pauseWhenHidden

Pauses the animation while the document tab is hidden to reduce unnecessary work.

Type boolean·Default true

fadeEdges

Applies a soft gradient mask at the viewport edges for a polished marquee fade.

Type boolean·Default false

selectable

When false, repeated copy uses `select-none` so users cannot highlight moving text.

Type boolean·Default true

href

Turns each repeated segment into a link. Only the first copy stays tabbable to avoid keyboard traps.

Type string

interactive

Keeps the animated track available to assistive tech. Defaults to `true` when `href` is provided.

Type boolean

aria-label

Accessible name for the announcement region. Falls back to joined `items` or plain-text `children`.

Type string

className

Optional class names merged onto the root ribbon for positioning, spacing, or typography overrides.

Type string

Registry bundle

Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.

Dependencies: none.

Contact

Additionally, if you find any bug or issue, feel free to raise an issue.

Build fast, responsive, and beautiful interfaces with ready-to-use components. Designed for developers.
Build fast, responsive, and beautiful interfaces with ready-to-use components. Designed for developers.