---
title: Card
description: "Displays a card with header, content, and footer."
---

```tsx
import * as stylex from '@stylexjs/stylex';

import { container } from '@/lib/constants.stylex';

import { Button } from '@/components/ui/button';
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';

export default function CardDemo() {
  return (
    <Card style={styles.card}>
      <CardHeader>
        <CardTitle>Create project</CardTitle>
        <CardDescription>Deploy your new project in one click.</CardDescription>
      </CardHeader>
      <CardContent>
        <Input placeholder="Project name" />
      </CardContent>
      <CardFooter>
        <Button>Deploy</Button>
        <Button variant="ghost">Cancel</Button>
      </CardFooter>
    </Card>
  );
}

const styles = stylex.create({
  card: {
    width: container.md,
  },
});
```

## Install

```bash
npx shadcn@latest add @madeui/card
```

## Usage

```tsx
import {
  Card,
  CardAction,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
```

## Composition

```tsx
<Card>
  <CardHeader>
    <CardTitle />
    <CardDescription />
    <CardAction />
  </CardHeader>
  <CardContent />
  <CardFooter />
</Card>
```

## Action

`CardAction` pins a slot (typically a button) to the top-right of `CardHeader`, spanning the title and description rows.

```tsx
import * as stylex from '@stylexjs/stylex';

import { Button } from '@/components/ui/button';
import {
  Card,
  CardAction,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import { container } from '@/lib/constants.stylex';

export default function CardActionDemo() {
  return (
    <Card style={styles.card}>
      <CardHeader>
        <CardTitle>Notifications</CardTitle>
        <CardDescription>You have 3 unread messages.</CardDescription>
        <CardAction>
          <Button size="sm" variant="ghost">
            Mark all read
          </Button>
        </CardAction>
      </CardHeader>
      <CardContent>
        <p>New comment on your pull request.</p>
      </CardContent>
    </Card>
  );
}

const styles = stylex.create({
  card: {
    width: container.md,
  },
});
```

## Small

Set `size="sm"` on `Card` for tighter padding across the header, content, and footer.

```tsx
import * as stylex from '@stylexjs/stylex';

import { Button } from '@/components/ui/button';
import { Card, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
import { container } from '@/lib/constants.stylex';

export default function CardSmallDemo() {
  return (
    <Card size="sm" style={styles.card}>
      <CardHeader>
        <CardTitle>Compact card</CardTitle>
        <CardDescription>Tighter padding for dense layouts.</CardDescription>
      </CardHeader>
      <CardFooter>
        <Button size="sm">Continue</Button>
      </CardFooter>
    </Card>
  );
}

const styles = stylex.create({
  card: {
    width: container.sm,
  },
});
```

## API reference

### Card

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `size` | `'md' \| 'sm'` | `'md'` | `sm` tightens the padding shared by `CardHeader`, `CardContent`, and `CardFooter`. |
| `style` | `StyleXStyles` | — | StyleX styles merged last — always win over the component's own styles. |

### Styling

`CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, `CardFooter` accept `style` (`StyleXStyles`, merged last so caller overrides always win) plus all native props of the element they render.
