Shadcn Marquee for React and Tailwind
Scrolls items in a horizontal container.
Installation
bunx --bun shadcn@latest add https://kit.dev/r/marquee.jsonpnpm dlx shadcn@latest add https://kit.dev/r/marquee.jsonnpx shadcn@latest add https://kit.dev/r/marquee.jsonyarn shadcn@latest add https://kit.dev/r/marquee.jsonInstall the following dependencies:
bun add @ark-ui/reactpnpm add @ark-ui/reactnpm install @ark-ui/reactyarn add @ark-ui/reactAdd the following animations to your globals.css.
@theme inline {
--animate-marquee-x: marqueeX var(--marquee-duration) linear infinite var(--marquee-delay);
--animate-marquee-y: marqueeY var(--marquee-duration) linear infinite var(--marquee-delay);
@keyframes marqueeX {
from { transform: translateX(0); }
to { transform: translateX(var(--marquee-translate)); }
}
@keyframes marqueeY {
from { transform: translateY(0); }
to { transform: translateY(var(--marquee-translate)); }
}
}Copy and paste the following code into your project.
"use client";
import { Marquee as ArkMarquee } from "@ark-ui/react/marquee";
import type React from "react";
import { cn } from "@/lib/utils";
interface MarqueeProps
extends Omit<React.ComponentProps<typeof ArkMarquee.Root>, "side"> {
/**
*
* @default "horizontal"
*/
orientation?: "horizontal" | "vertical";
/**
* Whether to show the edges of the marquee
*
* @default true
*/
showEdges?: boolean;
}
export const Marquee = (props: MarqueeProps) => {
const {
speed = 50,
showEdges = true,
spacing = "16px",
orientation = "horizontal",
className,
children,
...rest
} = props;
const side = orientation === "horizontal" ? "start" : "bottom";
return (
<ArkMarquee.Root
className={cn(
"group/marquee",
"relative",
"w-full max-w-full",
"isolate",
className
)}
data-orientation={orientation}
data-slot="marquee"
side={side}
spacing={spacing}
speed={speed}
{...rest}
>
{children}
{showEdges && (
<>
<MarqueeEdge side={orientation === "horizontal" ? "start" : "top"} />
<MarqueeEdge side={orientation === "horizontal" ? "end" : "bottom"} />
</>
)}
</ArkMarquee.Root>
);
};
export const MarqueeContent = (
props: React.ComponentProps<typeof ArkMarquee.Content>
) => {
const { className, ...rest } = props;
return (
<ArkMarquee.Viewport
className="flex overflow-hidden"
data-slot="marquee-viewport"
>
<ArkMarquee.Content
className={cn(
"flex",
"min-w-max",
"delay-(--marquee-delay)",
"data-[orientation=vertical]:animate-marquee-y data-[orientation=vertical]:flex-col",
"data-[orientation=horizontal]:animate-marquee-x data-[orientation=horizontal]:flex-row",
"data-reverse:direction-[reverse]!",
"group-data-paused/marquee:paused!",
className
)}
data-slot="marquee-content"
{...rest}
/>
</ArkMarquee.Viewport>
);
};
export const MarqueeItem = (
props: React.ComponentProps<typeof ArkMarquee.Item>
) => {
const { className, ...rest } = props;
return (
<ArkMarquee.Item
className={cn("w-full text-nowrap", className)}
data-slot="marquee-item"
{...rest}
/>
);
};
export const MarqueeEdge = (
props: React.ComponentProps<typeof ArkMarquee.Edge>
) => {
const { className, ...rest } = props;
return (
<ArkMarquee.Edge
className={cn(
"absolute z-10",
"group-data-[orientation=horizontal]/marquee:h-full group-data-[orientation=horizontal]/marquee:w-1/4",
"group-data-[orientation=vertical]/marquee:h-1/4 group-data-[orientation=vertical]/marquee:w-full",
"pointer-events-none",
"from-background to-transparent",
"data-[side=start]:bg-linear-to-r",
"data-[side=end]:bg-linear-to-l",
"data-[side=top]:bg-linear-to-b",
"data-[side=bottom]:bg-linear-to-t",
className
)}
data-slot="marquee-edge"
{...rest}
/>
);
};Update the import paths to match your project setup.
Anatomy
Marquee
├── MarqueeContent
└── MarqueeItemUsage
import {
Marquee,
MarqueeContent,
MarqueeItem,
} from "@/components/ui/marquee";<Marquee>
<MarqueeContent>
<MarqueeItem />
<MarqueeItem />
<MarqueeItem />
</MarqueeContent>
</Marquee>Orientation
Use the orientation prop to control the orientation of the marquee.
Horizontal
Vertical
Examples
Pause on hover
Use the pauseOnInteraction prop to pause the marquee on hover or focus.
Reverse
Use the reverse prop to scroll in the opposite direction.
Auto fill
Use the autoFill prop to automatically duplicate content to fill the container.
Spacing
Use the spacing prop to control the gap between items.
Fade
Use the showEdges prop to show or hide the gradient fade at the start and end of the marquee.
Custom speed
Use the speed prop (pixels per second) to control scroll speed.
API Reference
Marquee
Root component. Manages the scrolling viewport and animation.
| Prop | Type | Default |
|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal" |
speed | number | 50 |
spacing | string | "16px" |
showEdges | boolean | true |
autoFill | boolean | false |
pauseOnInteraction | boolean | false |
reverse | boolean | false |
className | string | - |
MarqueeContent
Viewport wrapper. Wrap MarqueeItem children with this. Animates content horizontally.
| Prop | Type | Default |
|---|---|---|
className | string | - |
asChild | boolean | - |
MarqueeItem
Single item in the scrolling marquee.
| Prop | Type | Default |
|---|---|---|
className | string | - |
asChild | boolean | - |
For a complete list of props, see the Ark UI documentation.