About
A marquee component continuously scrolls text, images, or videos in an infinite loop, with customizable speed, direction, and responsive design for engaging displays.
Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds 3D Testimonails to your project and fits it to your theme.
Code
How 3D Testimonails is used: the demo's code. The component's own source comes with a free account.
Usage.tsx
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Card, CardContent } from '@/components/ui/card';
import { Marquee } from '@/components/ui/3d-testimonails';
// Unique reviews data
const testimonials = [
{
name: 'Ava Green',
username: '@ava',
body: 'Cascade AI made my workflow 10x faster!',
img: 'https://cdn.21st.dev/assets/mirror/55/55cf6231499bcdc496f15ff1d28d4170ac9b99e9279495caa44fca70886d8b2e.jpg',
country: '๐ฆ๐บ Australia',
},
{
name: 'Ana Miller',
username: '@ana',
body: 'Vertical marquee is a game changer!',
img: 'https://cdn.21st.dev/assets/mirror/f0/f07b84f12ef125cbb837a7bd64da401992f5f62bd55fee10d01cd3dcc8abae80.jpg',
country: '๐ฉ๐ช Germany',
},
{
name: 'Mateo Rossi',
username: '@mat',
body: 'Animations are buttery smooth!',
img: 'https://cdn.21st.dev/assets/mirror/7c/7c0d2aa99715b15c218385f5679347782843c02f939d8eee6f9cb1cad6ba6ed0.jpg',
country: '๐ฎ๐น Italy',
},
{
name: 'Maya Patel',
username: '@maya',
body: 'Setup was a breeze!',
img: 'https://cdn.21st.dev/assets/mirror/f8/f8f2ddc445b6b2318430260bdebb665c9415865827230565aa42f57c9c794baf.jpg',
country: '๐ฎ๐ณ India',
},
{
name: 'Noah Smith',
username: '@noah',
body: 'Best marquee component!',
img: 'https://cdn.21st.dev/assets/mirror/ae/ae1d49872fdd6f8d9aa933f6ca8bce8cb1ba7e87dfb9d2926661184cb7bfe26d.jpg',
country: '๐บ๐ธ USA',
},
{
name: 'Lucas Stone',
username: '@luc',
body: 'Very customizable and smooth.',
img: 'https://cdn.21st.dev/assets/mirror/9a/9aac54d62e727561f6958213b8a3649230a3bba61ba5ddf63c69d3c6e4aecb0a.jpg',
country: '๐ซ๐ท France',
},
{
name: 'Haruto Sato',
username: '@haru',
body: 'Impressive performance on mobile!',
img: 'https://cdn.21st.dev/assets/mirror/e5/e55f3cdab57eb4084f7006cfe9f7f047e638e1b257a53498aaed14b83087152a.jpg',
country: '๐ฏ๐ต Japan',
},
{
name: 'Emma Lee',
username: '@emma',
body: 'Love the pause on hover feature!',
img: 'https://cdn.21st.dev/assets/mirror/03/03410c155320ba33ecb8d798807c6c9610f33b2b2acdd4ed961a68185806df79.jpg',
country: '๐จ๐ฆ Canada',
},
{
name: 'Carlos Ray',
username: '@carl',
body: 'Great for testimonials and logos.',
img: 'https://cdn.21st.dev/assets/mirror/b5/b58616f0d669595c9a42d60a0b9803364c9859f1c3db93a5e3dc408b603e03e8.jpg',
country: '๐ช๐ธ Spain',
},
];
function TestimonialCard({ img, name, username, body, country }: (typeof testimonials)[number]) {
return (
<Card className="w-50">
<CardContent>
<div className="flex items-center gap-2.5">
<Avatar className="size-9">
<AvatarImage src={img} alt="@reui_io" />
<AvatarFallback>{name[0]}</AvatarFallback>
</Avatar>
<div className="flex flex-col">
<figcaption className="text-sm font-medium text-foreground flex items-center gap-1">
{name} <span className="text-xs">{country}</span>
</figcaption>
<p className="text-xs font-medium text-muted-foreground">{username}</p>
</div>
</div>
<blockquote className="mt-3 text-sm text-econdary-foreground">{body}</blockquote>
</CardContent>
</Card>
);
}
export default function DemoOne() {
return (
<div className="border border-border rounded-lg relative flex h-96 w-full max-w-[800px] flex-row items-center justify-center overflow-hidden gap-1.5 [perspective:300px]">
<div
className="flex flex-row items-center gap-4"
style={{
transform:
'translateX(-100px) translateY(0px) translateZ(-100px) rotateX(20deg) rotateY(-10deg) rotateZ(20deg)',
}}
>
{/* Vertical Marquee (downwards) */}
<Marquee vertical pauseOnHover repeat={3} className="[--duration:40s]">
{testimonials.map((review) => (
<TestimonialCard key={review.username} {...review} />
))}
</Marquee>
{/* Vertical Marquee (upwards) */}
<Marquee vertical pauseOnHover reverse repeat={3} className="[--duration:40s]">
{testimonials.map((review) => (
<TestimonialCard key={review.username} {...review} />
))}
</Marquee>
{/* Vertical Marquee (upwards) */}
<Marquee vertical pauseOnHover repeat={3} className="[--duration:40s]">
{testimonials.map((review) => (
<TestimonialCard key={review.username} {...review} />
))}
</Marquee>
{/* Vertical Marquee (upwards) */}
<Marquee vertical pauseOnHover reverse repeat={3} className="[--duration:40s]">
{testimonials.map((review) => (
<TestimonialCard key={review.username} {...review} />
))}
</Marquee>
{/* Gradient overlays for vertical marquee */}
<div className="pointer-events-none absolute inset-x-0 top-0 h-1/4 bg-gradient-to-b from-background"></div>
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-1/4 bg-gradient-to-t from-background"></div>
<div className="pointer-events-none absolute inset-y-0 left-0 w-1/4 bg-gradient-to-r from-background"></div>
<div className="pointer-events-none absolute inset-y-0 right-0 w-1/4 bg-gradient-to-l from-background"></div>
</div>
</div>
);
}
















