Sawana Huang Avatar

Sawana Huang

Card

Fri Sep 12 2025

Customizable React card component built on shadcn/ui with size variants, TypeScript support, and flexible content organization

Install - Shadcn UI

我们默认使用 shadcn 作为我们的基础组件库,并且根据 shadcn 组件库的组件增改我们的样式。

另外,我们会使用的是 shadcn ui card 组件的副本,所以可能与您的版本有所不同,可以关注我们是"如何在原有基础上修改"的。

Card - shadcn/ui

Default Card

更改 shadcn ui 的默认 card,增加 size 变体控制。

Small Card
Compact card with reduced padding and spacing

This is a small-sized card perfect for displaying condensed information or in space-constrained layouts.

Default Card
Standard card with balanced padding and spacing

This is the default-sized card providing optimal balance between content space and visual hierarchy.

Large Card
Spacious card with generous padding and spacing

This is a large-sized card ideal for highlighting important content or creating premium layouts.

"use client";import { DefaultButton } from "../button/default-button";import {  Card,  CardContent,  CardDescription,  CardFooter,  CardHeader,  CardTitle,} from "./default-card";export function DefaultCardDemo() {  return (    <div className="flex min-h-[400px] flex-wrap items-start justify-center gap-6">      <Card size="sm" className="w-80">        <CardHeader>          <CardTitle>Small Card</CardTitle>          <CardDescription>            Compact card with reduced padding and spacing          </CardDescription>        </CardHeader>        <CardContent>          <p className="text-muted-foreground text-sm">            This is a small-sized card perfect for displaying condensed            information or in space-constrained layouts.          </p>        </CardContent>        <CardFooter>          <DefaultButton size="sm">Action</DefaultButton>        </CardFooter>      </Card>      <Card size="default" className="w-80">        <CardHeader>          <CardTitle>Default Card</CardTitle>          <CardDescription>            Standard card with balanced padding and spacing          </CardDescription>        </CardHeader>        <CardContent>          <p className="text-muted-foreground text-sm">            This is the default-sized card providing optimal balance between            content space and visual hierarchy.          </p>        </CardContent>        <CardFooter>          <DefaultButton>Action</DefaultButton>        </CardFooter>      </Card>      <Card size="lg" className="w-80">        <CardHeader>          <CardTitle>Large Card</CardTitle>          <CardDescription>            Spacious card with generous padding and spacing          </CardDescription>        </CardHeader>        <CardContent>          <p className="text-muted-foreground text-sm">            This is a large-sized card ideal for highlighting important content            or creating premium layouts.          </p>        </CardContent>        <CardFooter>          <DefaultButton size="lg">Action</DefaultButton>        </CardFooter>      </Card>    </div>  );}

大小

Small
Compact spacing

Reduced padding and gap for dense layouts.

Large
Generous spacing

Expanded padding and gap for premium feel.

Code

@/components/components/card/default-card.tsx
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";

import { cn } from "@/lib/utils";

const defaultCardVariants = cva(
  "bg-card text-card-foreground flex flex-col rounded-xl border shadow-sm",
  {
    variants: {
      size: {
        sm: "py-4 gap-4",
        default: "py-6 gap-6",
        lg: "py-8 gap-8",
      },
    },
    defaultVariants: {
      size: "default",
    },
  },
);

function Card({
  className,
  size,
  ...props
}: React.ComponentProps<"div"> & VariantProps<typeof defaultCardVariants>) {
  return (
    <div
      data-slot="card"
      data-card-size={size || "default"}
      className={cn(defaultCardVariants({ size, className }))}
      {...props}
    />
  );
}

function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card-header"
      className={cn(
        "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
        "[data-card-size='default']:px-6 [data-card-size='lg']:px-8 [data-card-size='sm']:px-4",
        className,
      )}
      {...props}
    />
  );
}

// ... other card components

export {
  Card,
  CardHeader,
  CardFooter,
  CardTitle,
  CardAction,
  CardDescription,
  CardContent,
  defaultCardVariants,
};