Luca Perullo
Components

Component

LiveNew

Marquee

Marquee CSS-only: nessun JS, solo transform e mask-image. Loop continuo (linear), pausa elegante su hover, reverse opzionale, durata e gap configurabili. Rispetta prefers-reduced-motion.

MotionCSS-onlyServer
Open in ClaudeSorgente

Esempio01

marquee.tsx

Note Proprietà animate: solo transform (GPU). I children vengono duplicati una volta dentro il componente per il loop seamless — non duplicarli a monte. Per stop & resume usa pauseOnHover (default).

Prompt LLM02

Incolla in Claude o ChatGPT per generare la tua variante. Include il contesto del brand, i token e i vincoli del progetto.

Prompt · marquee
Open in Claude
Sei un senior frontend engineer. Stai lavorando su un sito Next.js 16 + React 19 + Tailwind v4 in italiano, look chanhdai-inspired: colonna stretta 672px, Geist Sans + Geist Mono, hairline 1px, divisori a stripe diagonale, palette zinc.

Token CSS disponibili: --bg, --bg-alt, --fg, --fg-muted, --fg-soft, --border, --border-strong, --accent. Usa SEMPRE queste variabili tramite le utility tailwind generate (bg-bg, text-fg-muted, border-border, ecc.). Helper "cn" da "@/lib/utils". Niente librerie UI extra: solo lucide-react e tailwind-merge.

Genera un componente <Marquee>: striscia infinita CSS-only, hardware-accelerated.
Props:
- children: ReactNode
- direction?: "left" | "right" (default "left")
- durationSec?: number (default 36)
- gap?: string (default "1.5rem")
- pauseOnHover?: boolean (default true)
- fade?: boolean (default true)
- fadeWidth?: string (default "8%")
- className?: string

Implementazione:
- Container overflow-hidden con mask-image linear-gradient su entrambi i lati per fade-out (se fade=true).
- Renderizza i children DUE volte in due tracker affiancati con animation: marquee-x var(--marquee-duration) linear infinite.
- Keyframe in globals.css: from { translate3d(0,0,0) } to { translate3d(calc(-50% - var(--marquee-gap)/2), 0, 0) }.
- pauseOnHover via [animation-play-state:paused] in group-hover.
- prefers-reduced-motion: il media query globale collassa le durate, quindi resta statico.

Constraints: server component, niente JS, animazioni solo su transform, will-change-transform sui due tracker.

Output: file completo .tsx + lo snippet @keyframes da aggiungere a globals.css.

Uso tipico03

tsx
<Marquee durationSec={28} gap="0.75rem">
  {tags.map((t) => <Tag key={t}>{t}</Tag>)}
</Marquee>

Dipendenze04

npm
  • tailwind-merge
  • clsx
Interno
  • @/lib/utils#cn
  • globals.css#@keyframes marquee-x

Ti è servito? Dimmelo, oppure proponi il prossimo componente.