Marquee
An infinite horizontal scroller that pauses on hover.
2 examples
Installation
Run this in your project. It adds the files, installs the npm packages and anything this builds on, and sets up the theme:
npx shadcn@latest add https://kryptonite-ui.vercel.app/r/marquee.jsonInstall manually
Copy this into
components/kryptonite/Marquee.tsx:Marquee.tsximport type { CSSProperties, ReactNode } from 'react' import { cn } from '@/lib/utils' export type MarqueeProps = { children: ReactNode className?: string /** Seconds for one full loop */ duration?: number /** Space between items in pixels */ gap?: number /** Scroll right instead of left */ reverse?: boolean /** Pause while hovered */ pauseOnHover?: boolean /** Fade the left and right edges */ fade?: boolean } export function Marquee({ children, className, duration = 25, gap = 16, reverse = false, pauseOnHover = true, fade = true, }: MarqueeProps) { return ( <div className={cn( 'group overflow-hidden', fade && '[mask-image:linear-gradient(90deg,transparent,#000_10%,#000_90%,transparent)]', className, )} > <div style={ { '--duration': `${duration}s`, animationDirection: reverse ? 'reverse' : 'normal', } as CSSProperties } className={cn('flex w-max animate-marquee', pauseOnHover && 'group-hover:[animation-play-state:paused]')} > {/* Two copies so the loop is seamless; padding after each copy keeps spacing even at the seam */} <div className="flex shrink-0" style={{ gap, paddingRight: gap }}> {children} </div> <div className="flex shrink-0" style={{ gap, paddingRight: gap }} aria-hidden> {children} </div> </div> </div> ) }
Examples
Reverse
Feedback
Questions, bugs or ideas for Marquee? Post them here, or reply to someone else. Sign in with GitHub to comment.