Marquee

A customizable marquee effect for scrolling content horizontally or vertically

Installation

Run the following command

It will create a new file Marquee.tsx inside the components/effects directory.

mkdir -p components/effects && touch components/effects/Marquee.tsx

Paste the code

Open the newly created file and paste the following code:

"use client";
 
import { cn } from "@/lib/utils";
 
interface MarqueeProps {
  className?: string;
  reverse?: boolean;
  pauseOnHover?: boolean;
  children?: React.ReactNode;
  vertical?: boolean;
  repeat?: number;
  [key: string]: any;
}
 
export default function Marquee({
  className,
  reverse,
  pauseOnHover = false,
  children,
  vertical = false,
  repeat = 4,
  ...props
}: MarqueeProps) {
  return (
    <div
      {...props}
      className={cn(
        "group flex overflow-hidden p-2 [--duration:40s] [--gap:1rem] [gap:var(--gap)]",
        {
          "flex-row": !vertical,
          "flex-col": vertical,
        },
        className
      )}
    >
      {Array(repeat)
        .fill(0)
        .map((_, i) => (
          <div
            key={i}
            className={cn("flex shrink-0 justify-around [gap:var(--gap)]", {
              "animate-marquee flex-row": !vertical,
              "animate-marquee-vertical flex-col": vertical,
              "group-hover:[animation-play-state:paused]": pauseOnHover,
              "[animation-direction:reverse]": reverse,
            })}
          >
            {children}
          </div>
        ))}
    </div>
  );
}

Add the required CSS animations

You can add the animations in one of two ways:

Option 1: Global CSS

Add these animations to your global CSS file:

@keyframes marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(calc(-100% - var(--gap)));
  }
}
 
@keyframes marquee-vertical {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(calc(-100% - var(--gap)));
  }
}
 
.animate-marquee {
  animation: marquee var(--duration) linear infinite;
}
 
.animate-marquee-vertical {
  animation: marquee-vertical var(--duration) linear infinite;
}

Option 2: Tailwind Config Add these keyframes to your tailwind.config.js:

/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      keyframes: {
        marquee: {
          from: { transform: "translateX(0)" },
          to: { transform: "translateX(calc(-100% - var(--gap)))" },
        },
        "marquee-vertical": {
          from: { transform: "translateY(0)" },
          to: { transform: "translateY(calc(-100% - var(--gap)))" },
        },
      },
      animation: {
        marquee: "marquee var(--duration) linear infinite",
        "marquee-vertical": "marquee-vertical var(--duration) linear infinite",
      },
    },
  },
  // ... rest of your config
};

Props

PropTypeDefaultDescription
classNamestringundefinedAdditional CSS classes to apply
reversebooleanfalseReverses the scroll direction
pauseOnHoverbooleanfalsePauses the animation when hovering
verticalbooleanfalseSwitches to vertical scrolling
repeatnumber4Number of times to repeat the content
childrenReact.ReactNoderequiredContent to be scrolled

CSS Variables

VariableDefaultDescription
--duration40sAnimation duration
--gap1remGap between repeated elements

Usage

import { Marquee } from "@/components/effects/Marquee";
 
export default function Example() {
  return (
    <Marquee className="bg-muted" pauseOnHover>
      <span className="px-4">Item 1</span>
      <span className="px-4">Item 2</span>
      <span className="px-4">Item 3</span>
    </Marquee>
  );
}

Vertical Marquee

import { Marquee } from "@/components/effects/Marquee";
 
export default function Example() {
  return (
    <Marquee vertical className="h-[300px]">
      <span className="py-4">Item 1</span>
      <span className="py-4">Item 2</span>
      <span className="py-4">Item 3</span>
    </Marquee>
  );
}

Custom Speed

You can adjust the animation speed by modifying the --duration CSS variable:

<Marquee className="[--duration:20s]">{/* Content */}</Marquee>

Credits

Built by Bossadi Zenith