Marquee

Animated

A strip that scrolls its content on a seamless loop.

View Source

#Installation

npx @dinachi/cli@latest add marquee

#Usage

tsx
import { Marquee } from "@/components/ui/marquee"
tsx
<Marquee>
  {logos.map((logo) => (
    <img key={logo.name} src={logo.src} alt={logo.name} className="h-8" />
  ))}
</Marquee>

#Examples

#When it moves

The loop only runs when it has something to say.

  • Content narrower than the container sits still. Sliding a gap past the reader adds nothing they could not already see. The strip measures itself, so this needs no prop.
  • It stops while scrolled out of view, and while hovered or focused.
  • Pausing brakes rather than stops, over 160ms. Stopping dead reads as a dropped frame. Resuming takes 240ms, since it answers nothing the reader is waiting on.
  • Touch does not count as hover. A tap fires pointerenter with no matching pointerleave, which would strand the strip until the next tap elsewhere.

#Accessibility

  • The duplicate track is aria-hidden and inert. A seamless loop needs a second copy, and its links are neither announced twice nor reachable by tab.
  • Focus pauses the strip regardless of pauseOnHover, so a keyboard user never loses the element they are on.
  • Reduced motion turns the strip into an ordinary horizontal scroller. The container becomes focusable, since nothing carries the overflow into view on its own.

#API Reference

PropTypeDefaultDescription
durationnumber24Seconds for one full pass of the content
direction"left" | "right""left"Travel direction
pauseOnHoverbooleantrueBrake while hovered. Focus pauses the strip regardless
fadebooleantrueFade the leading and trailing edges. Applies only while the strip is moving