Animated Tabs
- Source
- Aceternity UI ↗
- Author
- Aceternity UI
- Licence
- Aceternity UI licence (free component)
Loading…
Picking a tab slides the pill across and moves that card to the front of a 3D stack that fans out on hover.
Code
"use client";
import { Tabs } from "@/lab/aceternity/ui/tabs";
const panel =
"relative h-full w-full overflow-hidden rounded-2xl bg-gradient-to-br from-purple-700 to-violet-900 p-[4cqw] text-[clamp(1rem,4cqw,2.25rem)] font-bold text-white";
const tabs = [
{ title: "Product", value: "product", label: "Product Tab" },
{ title: "Services", value: "services", label: "Services tab" },
{ title: "Playground", value: "playground", label: "Playground tab" },
{ title: "Content", value: "content", label: "Content tab" },
{ title: "Random", value: "random", label: "Random tab" },
].map(({ label, ...tab }) => ({
...tab,
content: (
<div className={panel}>
<p>{label}</p>
<DummyContent />
</div>
),
}));
export default function TabsDemo() {
return (
<div className="@container relative flex h-full w-full flex-col items-start justify-start overflow-hidden px-[4cqw] pt-[3cqw] pb-[2cqw] [perspective:1000px]">
<Tabs
tabs={tabs}
tabClassName="px-[1.6cqw] py-[0.8cqw] text-[clamp(0.65rem,1.6cqw,1rem)]"
contentClassName="mt-[9cqw] h-[calc(100%-9cqw)]"
/>
</div>
);
}
// The original shows a /linear.webp screenshot; a drawn stand-in keeps the lab asset-free.
function DummyContent() {
return (
<div className="absolute inset-x-0 -bottom-[3cqw] mx-auto flex h-[62%] w-[90%] gap-[1.5cqw] rounded-xl border border-white/10 bg-neutral-950 p-[1.5cqw]">
<div className="flex w-1/4 flex-col gap-[1cqw]">
{Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="h-[1.2cqw] rounded-full bg-white/15" style={{ width: `${90 - i * 9}%` }} />
))}
</div>
<div className="grid flex-1 grid-cols-3 gap-[1cqw]">
{Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="rounded-lg border border-white/10 bg-white/5" />
))}
</div>
</div>
);
}
Prompt
Build "Animated Tabs", a navigation animation. What it does: Picking a tab slides the pill across and moves that card to the front of a 3D stack that fans out on hover. Write it as a single self-contained React component in TypeScript that fills its parent (w-full h-full), styled with Tailwind CSS, using motion. Technique: the Motion library. It sits on a light background, in a 16:10 frame. Respect prefers-reduced-motion with a still state, pause work when the element is off screen, and keep it accessible. Original: https://ui.aceternity.com/components/tabs (Aceternity UI, Aceternity UI licence (free component)).