Cards are usually used to show some basic information and then allow the user to interact with it to show more data. The size of the card is determined by the content within.
The Card component can be used to add elevation to content by adding a surface
background color and box shadow. The Card is normally used with the
CardContent component to add default padding around the content and apply the
text secondary color.
Here is some text to display.
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement } from "react";
export default function SimpleExample(): ReactElement {
return (
<Card>
<CardContent>
<Typography margin="none">Here is some text to display.</Typography>
</CardContent>
</Card>
);
}
A Card can gain width: 100% by enabling the fullWidth prop.
Here is some text to display.
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement } from "react";
export default function FullWidthCardExample(): ReactElement {
return (
<Card fullWidth>
<CardContent>
<Typography margin="none">Here is some text to display.</Typography>
</CardContent>
</Card>
);
}
A Card can gain additional box shadow while hovered by enabling the raisable
prop.
The raisable card is not really noticeable in dark mode by default. Custom box shadow styles will be required.
Here is some text to display.
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement } from "react";
export default function RaisableExample(): ReactElement {
return (
<Card raisable>
<CardContent>
<Typography margin="none">Here is some text to display.</Typography>
</CardContent>
</Card>
);
}
A Card can gain a border instead of box-shadow by enabling the bordered
prop.
Here is some text to display.
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement } from "react";
export default function BorderedExample(): ReactElement {
return (
<Card bordered>
<CardContent disableSecondaryColor>
<Typography margin="none">Here is some text to display.</Typography>
</CardContent>
</Card>
);
}
Another main use case for cards is to display some sort of image or video along with a description using the responsive item components.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ut eleifend odio. Vivamus quis quam eget augue facilisis laoreet. Aliquam egestas turpis pellentesque cursus porta. Vivamus nisl odio, maximus vel lacinia non, suscipit quis nibh. Sed et lacus tempor, interdum nisl ornare, feugiat arcu. Suspendisse aliquam malesuada dui, in dignissim velit maximus vitae. Cras ac mattis libero. Proin feugiat justo nec nisi sodales, et gravida augue faucibus. Maecenas quis porttitor nunc. Suspendisse congue ipsum arcu, id aliquam ante dignissim non. Donec maximus, sapien in faucibus molestie, eros nisi ornare neque, et vulputate augue velit vel ante. Phasellus rhoncus, elit cursus accumsan viverra, mi lectus dictum elit, non vehicula diam nunc non lectus. Sed elementum, risus eget fermentum accumsan, nunc ante commodo diam, eget pulvinar risus velit eu sapien. Nunc vitae pellentesque nisl.
Maecenas lacinia enim ut risus pellentesque euismod. Vestibulum gravida, risus non condimentum volutpat, orci elit laoreet elit, in auctor eros orci non quam. Proin ut tellus et est dignissim efficitur. Aliquam erat volutpat. Proin pellentesque metus sit amet libero auctor aliquet. Donec scelerisque erat in magna sagittis hendrerit. Sed pulvinar enim mattis mauris sodales semper. Mauris eu urna at arcu dapibus pretium et in ligula. Sed vel vestibulum nunc.
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { CardTitle } from "@react-md/core/card/CardTitle";
import { ResponsiveItem } from "@react-md/core/responsive-item/ResponsiveItem";
import { ResponsiveItemOverlay } from "@react-md/core/responsive-item/ResponsiveItemOverlay";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement } from "react";
export default function CardWithMediaExample(): ReactElement {
return (
<Card>
<ResponsiveItem fullWidth>
<img src="https://picsum.photos/600/337?image=402" alt="" />
<ResponsiveItemOverlay>
<CardTitle>Wow</CardTitle>
</ResponsiveItemOverlay>
</ResponsiveItem>
<CardContent>
<Typography>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ut
eleifend odio. Vivamus quis quam eget augue facilisis laoreet. Aliquam
egestas turpis pellentesque cursus porta. Vivamus nisl odio, maximus
vel lacinia non, suscipit quis nibh. Sed et lacus tempor, interdum
nisl ornare, feugiat arcu. Suspendisse aliquam malesuada dui, in
dignissim velit maximus vitae. Cras ac mattis libero. Proin feugiat
justo nec nisi sodales, et gravida augue faucibus. Maecenas quis
porttitor nunc. Suspendisse congue ipsum arcu, id aliquam ante
dignissim non. Donec maximus, sapien in faucibus molestie, eros nisi
ornare neque, et vulputate augue velit vel ante. Phasellus rhoncus,
elit cursus accumsan viverra, mi lectus dictum elit, non vehicula diam
nunc non lectus. Sed elementum, risus eget fermentum accumsan, nunc
ante commodo diam, eget pulvinar risus velit eu sapien. Nunc vitae
pellentesque nisl.
</Typography>
<Typography>
Maecenas lacinia enim ut risus pellentesque euismod. Vestibulum
gravida, risus non condimentum volutpat, orci elit laoreet elit, in
auctor eros orci non quam. Proin ut tellus et est dignissim efficitur.
Aliquam erat volutpat. Proin pellentesque metus sit amet libero auctor
aliquet. Donec scelerisque erat in magna sagittis hendrerit. Sed
pulvinar enim mattis mauris sodales semper. Mauris eu urna at arcu
dapibus pretium et in ligula. Sed vel vestibulum nunc.
</Typography>
</CardContent>
</Card>
);
}
There are a few additional card components that can be used:
CardHeader - A simple flex container with padding and column-gap.
Normally renders the CardTitle, CardSubtitle, and addons.
CardTitle - Simple wrapper around the Typography component to render
as headline-5 with no margin.CardSubtitle - Simple wrapper around the Typography to render as
subtitle-2 with no margin and the secondary text color.CardContent - Adds padding and applies the secondary text color.CardFooter - Simple wrapper around the Box component that defaults to
align="end" and 0.5rem padding. This is normally used to render Button
components.Here is some text to display.
import { Button } from "@react-md/core/button/Button";
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { CardFooter } from "@react-md/core/card/CardFooter";
import { CardHeader } from "@react-md/core/card/CardHeader";
import { CardSubtitle } from "@react-md/core/card/CardSubtitle";
import { CardTitle } from "@react-md/core/card/CardTitle";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement } from "react";
export default function AdditionalCardComponentsExample(): ReactElement {
return (
<Card>
<CardHeader>
<CardTitle>Main Title</CardTitle>
<CardSubtitle>Subtitle</CardSubtitle>
</CardHeader>
<CardContent>
<Typography margin="none">Here is some text to display.</Typography>
</CardContent>
<CardFooter>
<Button>Action 1</Button>
<Button>Action 2</Button>
</CardFooter>
</Card>
);
}
The CardHeader component can render additional content before and after the
children by using the beforeAddon and afterAddon props. The main benefits
to these props are that they will not automatically be truncated with ellipsis
when overflowing.
import { Avatar } from "@react-md/core/avatar/Avatar";
import { Button } from "@react-md/core/button/Button";
import { Card } from "@react-md/core/card/Card";
import { CardHeader } from "@react-md/core/card/CardHeader";
import { CardSubtitle } from "@react-md/core/card/CardSubtitle";
import { CardTitle } from "@react-md/core/card/CardTitle";
import CloseIcon from "@react-md/material-icons/CloseIcon";
import { type ReactElement } from "react";
export default function CardHeaderAddonsExample(): ReactElement {
return (
<Card style={{ maxWidth: "30rem" }} fullWidth>
<CardHeader
beforeAddon={<Avatar>A</Avatar>}
afterAddon={
<Button buttonType="icon">
<CloseIcon />
</Button>
}
>
<CardTitle>
A main title that should have trailing ellipsis since it is so long
</CardTitle>
<CardSubtitle>
A subtitle that should have trailing ellipsis since it is so long
</CardSubtitle>
</CardHeader>
</Card>
);
}
Multiple cards can be rendered in a grid using the Box component.
A common pattern for cards are to have expandable sections to show more information when space is limited. There is no built-in functionality for this in cards but can be easily implemented using the Collapse component.
If a Card should be clickable, use the ClickableCard component instead to
apply the required accessibility changes and styling.
"use client";
import { CardContent } from "@react-md/core/card/CardContent";
import { ClickableCard } from "@react-md/core/card/ClickableCard";
import { Dialog } from "@react-md/core/dialog/Dialog";
import { DialogHeader } from "@react-md/core/dialog/DialogHeader";
import { DialogTitle } from "@react-md/core/dialog/DialogTitle";
import { useToggle } from "@react-md/core/useToggle";
import { type ReactElement } from "react";
export default function ClickableCardExample(): ReactElement {
const { toggled, enable, disable } = useToggle();
return (
<>
<ClickableCard onClick={enable}>
<CardContent>Wow</CardContent>
</ClickableCard>
<Dialog
visible={toggled}
onRequestClose={disable}
aria-label="Bigger Wow"
>
<DialogHeader>
<DialogTitle>WOW!</DialogTitle>
</DialogHeader>
</Dialog>
</>
);
}