Docs
Flipping cards

Flipping cards

A list of flip cards arranged, each card representing an item or concept. Hovering on a card flips it to reveal additional details.

requires interactionhover

Installation

Install dependencies

This uses Marquee for the text. Install it by following the instructions here.

npm install framer-motion

Run the following command

It will create a new file called flipping-cards.tsx inside the components/animata/list directory.

mkdir -p components/animata/list && touch components/animata/list/flipping-cards.tsx

Paste the code

Open the newly created file and paste the following code:

import { PlusCircle } from "lucide-react";
 
import Marquee from "@/animata/container/marquee";
import { cn } from "@/lib/utils";
 
interface CardProps {
  show: React.ReactNode;
  reveal: React.ReactNode;
}
 
interface CardDetailsProps extends React.HTMLAttributes<HTMLDivElement> {
  title: string;
  font: string;
  image: string;
  index?: number;
}
 
interface FlippingCardProps {
  list: CardDetailsProps[];
}
 
const Card = ({ show, reveal }: CardProps) => {
  const common = "absolute flex w-full h-full  [backface-visibility:hidden]";
  return (
    <div className={cn("group h-60 w-48 [perspective:1000px]")}>
      <div
        className={cn(
          "relative h-full transition-all delay-75 duration-500 ease-linear [transform-style:preserve-3d] group-hover:[transform:rotateY(-180deg)]",
        )}
      >
        <div className={cn("bg-white", common)}>{show}</div>
        <div
          className={cn("[transform:rotateY(180deg)]", common)}
          style={{
            // Note: Set your own color over here
            backgroundColor: `#${(((1 << 24) * Math.random()) | 0).toString(16).padStart(6, "0")}`,
          }}
        >
          {reveal}
        </div>
      </div>
    </div>
  );
};
 
const CardDetails = ({ title, image, font, index }: CardDetailsProps) => {
  return (
    <Card
      show={
        <div className="flex w-full flex-col border-[1px] border-black/15 px-3 py-4 text-sm">
          <span className="border-t-2 border-black pt-1">{font}</span>
 
          <span className="mt-4 border-b-2 border-black px-1 font-serif text-8xl">{title}</span>
          <div className="mt-12 flex items-center justify-between">
            <span>{index}</span>
            <PlusCircle size={18} />
          </div>
        </div>
      }
      reveal={
        <div className="flex w-full flex-col justify-between overflow-hidden py-4 text-sm">
          <img alt="" src={image} className="size-32 px-2" />
          <Marquee className="font-serif text-5xl text-white" applyMask={false}>
            {font.split(" ")[0]}
          </Marquee>
          <div className="flex items-center justify-between px-3">
            <span className="text-white">See more</span>
            <PlusCircle size={18} color="white" />
          </div>
        </div>
      }
    />
  );
};
 
export default function FlippingCard({ list }: FlippingCardProps) {
  return (
    <div className="grid grid-cols-3 gap-5 max-sm:grid-cols-2">
      {list.map((item, index) => (
        <CardDetails
          key={`card_${index}`}
          index={index}
          title={item.title}
          font={item.font}
          image={item.image}
        />
      ))}
    </div>
  );
}

Credits

Built by Bibek Bhattarai