- Accordion
- Alert Dialog
- Animated Gradient Text
- Animated Shiny Text
- Avatar
- Badge
- Bento Box
- Bento Grid
- Border Beam
- Breadcrumbs
- Card
- Checkbox
- Custom Cursor
- Dialog
- Glow Border
- Glow Card
- Hyper Text
- Logo Beam
- Marquee
- Number Counter
- Popover
- Ripple Button
- Scroll Area
- Separator
- Shimmer Button
- Shinny Icons
- Tabs
- Terminal
- Text Animate
- Theme Toggler
- Typing Animation
- Word Rotate
John Mark
Unlock data-driven decisions with precision analytics.
Thomas Shelby
Experience seamless performance at scale.
Larry Page
Enterprise-grade protection for your assets.
Berry White
Connect across borders with effortless integration.
Susan Collins
Visualize trends and forecasts in real-time.
John Mark
Unlock data-driven decisions with precision analytics.
Thomas Shelby
Experience seamless performance at scale.
Larry Page
Enterprise-grade protection for your assets.
Berry White
Connect across borders with effortless integration.
Susan Collins
Visualize trends and forecasts in real-time.
John Mark
Unlock data-driven decisions with precision analytics.
Thomas Shelby
Experience seamless performance at scale.
Larry Page
Enterprise-grade protection for your assets.
Berry White
Connect across borders with effortless integration.
Susan Collins
Visualize trends and forecasts in real-time.
John Mark
Unlock data-driven decisions with precision analytics.
Thomas Shelby
Experience seamless performance at scale.
Larry Page
Enterprise-grade protection for your assets.
Berry White
Connect across borders with effortless integration.
Susan Collins
Visualize trends and forecasts in real-time.
import { cn } from "@/lib/utils"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Badge } from "@/components/ui/badge"
import { Marquee } from "@/components/ui/marquee"
const features = [
{
avatar:
"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=150&h=150&fit=crop&crop=face",
title: "John Mark",
description: "Unlock data-driven decisions with precision analytics.",
badge: "Frontend",
},
{
avatar:
"https://images.unsplash.com/photo-1494790108755-2616b612b786?w=150&h=150&fit=crop&crop=face",
title: "Thomas Shelby",
description: "Experience seamless performance at scale.",
badge: "Designer",
},
{
avatar:
"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=150&h=150&fit=crop&crop=face",
title: "Larry Page",
description: "Enterprise-grade protection for your assets.",
badge: "Expert",
},
{
avatar:
"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=150&h=150&fit=crop&crop=face",
title: "Berry White",
description: "Connect across borders with effortless integration.",
badge: "Lawyer",
},
{
avatar:
"https://images.unsplash.com/photo-1494790108755-2616b612b786?w=150&h=150&fit=crop&crop=face",
title: "Susan Collins",
description: "Visualize trends and forecasts in real-time.",
badge: "Manager",
},
]
const FeatureCard = ({
avatar,
title,
description,
badge,
}: {
avatar: string
title: string
description: string
badge: string
}) => {
return (
<div
className={cn(
"relative h-full w-74 cursor-pointer overflow-hidden rounded-2xl border p-6 transition-all duration-200 hover:scale-95",
// light styles
"border-border bg-card hover:bg-accent/20",
// dark styles
"dark:border-border dark:bg-card dark:hover:bg-accent/20"
)}
>
<div className="mb-4 text-4xl">
<Avatar className="h-12 w-12">
<AvatarImage src={avatar} alt={title} />
<AvatarFallback className="bg-primary text-primary-foreground">
{title.charAt(0)}
</AvatarFallback>
</Avatar>
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
<h3 className="text-foreground text-lg font-semibold">{title}</h3>
<Badge variant="secondary" className="text-xs">
{badge}
</Badge>
</div>
<p className="text-muted-foreground text-sm">{description}</p>
</div>
</div>
)
}
export function FeatureMarqueeDemo() {
return (
<div className="relative flex w-full flex-col items-center justify-center overflow-hidden">
<Marquee pauseOnHover className="w-full max-w-6xl [--gap:1.5rem]">
{features.map((feature, index) => (
<FeatureCard key={index} {...feature} />
))}
</Marquee>
</div>
)
}
Installation
pnpm dlx shadcn@latest add https://ebonui.com/r/marquee.json
Examples
Vertical
Crafting pixel-perfect experiences that delight users worldwide.
Lead Designer
Building robust backends and sleek frontends with a passion for code.
Full-Stack Dev
Crafting pixel-perfect experiences that delight users worldwide.
Lead Designer
Building robust backends and sleek frontends with a passion for code.
Full-Stack Dev
Crafting pixel-perfect experiences that delight users worldwide.
Lead Designer
Building robust backends and sleek frontends with a passion for code.
Full-Stack Dev
Crafting pixel-perfect experiences that delight users worldwide.
Lead Designer
Building robust backends and sleek frontends with a passion for code.
Full-Stack Dev
Bridging visions to reality, one feature at a time.
Product Manager
Uncovering user needs to shape intuitive journeys.
UX Researcher
Bridging visions to reality, one feature at a time.
Product Manager
Uncovering user needs to shape intuitive journeys.
UX Researcher
Bridging visions to reality, one feature at a time.
Product Manager
Uncovering user needs to shape intuitive journeys.
UX Researcher
Bridging visions to reality, one feature at a time.
Product Manager
Uncovering user needs to shape intuitive journeys.
UX Researcher
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Marquee } from "@/components/ui/marquee"
const teamMembers = [
{
name: "Alex Rivera",
role: "Lead Designer",
bio: "Crafting pixel-perfect experiences that delight users worldwide.",
avatar:
"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=150&h=150&fit=crop&crop=face",
badge: "Design",
},
{
name: "Jordan Lee",
role: "Full-Stack Dev",
bio: "Building robust backends and sleek frontends with a passion for code.",
avatar:
"https://images.unsplash.com/photo-1494790108755-2616b612b786?w=150&h=150&fit=crop&crop=face",
badge: "Engineering",
},
{
name: "Taylor Kim",
role: "Product Manager",
bio: "Bridging visions to reality, one feature at a time.",
avatar:
"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=150&h=150&fit=crop&crop=face",
badge: "Product",
},
{
name: "Casey Patel",
role: "UX Researcher",
bio: "Uncovering user needs to shape intuitive journeys.",
avatar:
"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=150&h=150&fit=crop&crop=face",
badge: "Research",
},
]
const leftColumn = teamMembers.slice(0, teamMembers.length / 2)
const rightColumn = teamMembers.slice(teamMembers.length / 2)
const TeamCard = ({
avatar,
name,
role,
bio,
badge,
}: {
avatar: string
name: string
role: string
bio: string
badge: string
}) => {
return (
<Card className="h-full w-48 border-0 shadow-sm transition-shadow duration-300 hover:shadow-md">
<CardHeader className="pb-2">
<div className="flex items-center gap-3">
<Avatar className="h-12 w-12">
<AvatarImage src={avatar} alt={name} />
<AvatarFallback className="bg-primary text-primary-foreground">
{name.charAt(0)}
</AvatarFallback>
</Avatar>
<div className="space-y-1">
<CardTitle className="text-base leading-tight font-semibold">
{name}
</CardTitle>
<Badge variant="outline" className="text-xs capitalize">
{badge}
</Badge>
</div>
</div>
</CardHeader>
<CardContent>
<p className="text-muted-foreground text-xs leading-relaxed">{bio}</p>
<p className="text-primary mt-2 text-xs font-medium">{role}</p>
</CardContent>
</Card>
)
}
export function TeamMarqueeVerticalDemo() {
return (
<div className="relative flex h-[500px] w-full flex-row items-center justify-center overflow-hidden">
<Marquee vertical pauseOnHover className="[--duration:20s]">
{leftColumn.map((member, index) => (
<TeamCard key={index} {...member} />
))}
</Marquee>
<Marquee vertical reverse pauseOnHover className="[--duration:20s]">
{rightColumn.map((member, index) => (
<TeamCard key={index} {...member} />
))}
</Marquee>
</div>
)
}
3D
Lead Designer
Crafting pixel-perfect experiences that delight users worldwide.
Full-Stack Dev
Building robust backends and sleek frontends with a passion for code.
Lead Designer
Crafting pixel-perfect experiences that delight users worldwide.
Full-Stack Dev
Building robust backends and sleek frontends with a passion for code.
Lead Designer
Crafting pixel-perfect experiences that delight users worldwide.
Full-Stack Dev
Building robust backends and sleek frontends with a passion for code.
Lead Designer
Crafting pixel-perfect experiences that delight users worldwide.
Full-Stack Dev
Building robust backends and sleek frontends with a passion for code.
Product Manager
Bridging visions to reality, one feature at a time.
UX Researcher
Uncovering user needs to shape intuitive journeys.
Product Manager
Bridging visions to reality, one feature at a time.
UX Researcher
Uncovering user needs to shape intuitive journeys.
Product Manager
Bridging visions to reality, one feature at a time.
UX Researcher
Uncovering user needs to shape intuitive journeys.
Product Manager
Bridging visions to reality, one feature at a time.
UX Researcher
Uncovering user needs to shape intuitive journeys.
Lead Designer
Crafting pixel-perfect experiences that delight users worldwide.
Full-Stack Dev
Building robust backends and sleek frontends with a passion for code.
Lead Designer
Crafting pixel-perfect experiences that delight users worldwide.
Full-Stack Dev
Building robust backends and sleek frontends with a passion for code.
Lead Designer
Crafting pixel-perfect experiences that delight users worldwide.
Full-Stack Dev
Building robust backends and sleek frontends with a passion for code.
Lead Designer
Crafting pixel-perfect experiences that delight users worldwide.
Full-Stack Dev
Building robust backends and sleek frontends with a passion for code.
Product Manager
Bridging visions to reality, one feature at a time.
UX Researcher
Uncovering user needs to shape intuitive journeys.
Product Manager
Bridging visions to reality, one feature at a time.
UX Researcher
Uncovering user needs to shape intuitive journeys.
Product Manager
Bridging visions to reality, one feature at a time.
UX Researcher
Uncovering user needs to shape intuitive journeys.
Product Manager
Bridging visions to reality, one feature at a time.
UX Researcher
Uncovering user needs to shape intuitive journeys.
import { cn } from "@/lib/utils"
import { Marquee } from "@/components/ui/marquee"
const teamMembers = [
{
name: "Alex Rivera",
role: "Lead Designer",
bio: "Crafting pixel-perfect experiences that delight users worldwide.",
avatar:
"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=150&h=150&fit=crop&crop=face",
},
{
name: "Jordan Lee",
role: "Full-Stack Dev",
bio: "Building robust backends and sleek frontends with a passion for code.",
avatar:
"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=150&h=150&fit=crop&crop=face",
},
{
name: "Taylor Kim",
role: "Product Manager",
bio: "Bridging visions to reality, one feature at a time.",
avatar:
"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=150&h=150&fit=crop&crop=face",
},
{
name: "Casey Patel",
role: "UX Researcher",
bio: "Uncovering user needs to shape intuitive journeys.",
avatar:
"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=150&h=150&fit=crop&crop=face",
},
]
const firstRow = teamMembers.slice(0, teamMembers.length / 2)
const secondRow = teamMembers.slice(teamMembers.length / 2)
const thirdRow = teamMembers.slice(0, teamMembers.length / 2)
const fourthRow = teamMembers.slice(teamMembers.length / 2)
const TeamCard = ({
avatar,
name,
role,
bio,
}: {
avatar: string
name: string
role: string
bio: string
}) => {
return (
<figure
className={cn(
"relative h-full w-fit cursor-pointer overflow-hidden rounded-xl border p-4 sm:w-36",
// light styles
"border-gray-950/[.1] bg-gray-950/[.01] hover:bg-gray-950/[.05]",
// dark styles
"dark:border-gray-50/[.1] dark:bg-gray-50/[.10] dark:hover:bg-gray-50/[.15]"
)}
>
<div className="flex flex-row items-center gap-2">
<img
className="rounded-full"
width="32"
height="32"
alt=""
src={avatar}
/>
<div className="flex flex-col">
<figcaption className="text-sm font-medium dark:text-white">
{name}
</figcaption>
<p className="text-xs font-medium dark:text-white/40">{role}</p>
</div>
</div>
<blockquote className="mt-2 text-sm">{bio}</blockquote>
</figure>
)
}
export function Marquee3D() {
return (
<div className="relative flex h-96 w-full flex-row items-center justify-center gap-4 overflow-hidden [perspective:300px]">
<div
className="flex flex-row items-center gap-4"
style={{
transform:
"translateX(0px) translateY(-50px) translateZ(-150px) rotateX(15deg) rotateY(0deg) rotateZ(0deg)",
}}
>
<Marquee pauseOnHover vertical className="[--duration:20s]">
{firstRow.map((review) => (
<TeamCard key={review.role} {...review} />
))}
</Marquee>
<Marquee reverse pauseOnHover className="[--duration:20s]" vertical>
{secondRow.map((review) => (
<TeamCard key={review.role} {...review} />
))}
</Marquee>
<Marquee reverse pauseOnHover className="[--duration:20s]" vertical>
{thirdRow.map((review) => (
<TeamCard key={review.role} {...review} />
))}
</Marquee>
<Marquee pauseOnHover className="[--duration:20s]" vertical>
{fourthRow.map((review) => (
<TeamCard key={review.role} {...review} />
))}
</Marquee>
</div>
<div className="from-background pointer-events-none absolute inset-x-0 top-0 h-1/4 bg-gradient-to-b"></div>
<div className="from-background pointer-events-none absolute inset-x-0 bottom-0 h-1/4 bg-gradient-to-t"></div>
<div className="from-background pointer-events-none absolute inset-y-0 left-0 w-1/4 bg-gradient-to-r"></div>
<div className="from-background pointer-events-none absolute inset-y-0 right-0 w-1/4 bg-gradient-to-l"></div>
</div>
)
}
Usage
import { Marquee } from "@/components/ui/marquee"<Marquee>
<span>Next.js</span>
<span>React</span>
<span>TypeScript</span>
<span>Tailwind CSS</span>
</Marquee>Props
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | The class name to apply to the component. |
reverse | boolean | false | Whether or not to reverse the direction of the marquee. |
pauseOnHover | boolean | false | Whether or not to pause the marquee when the user hovers over the component. |
vertical | boolean | false | Whether or not to display the marquee vertically. |
children | node | - | The content to display in the marquee. |
repeat | number | 4 | The number of times to repeat the content. |