Card

A bounded surface for one thing: a title, a body, an optional cover and a row of actions along the bottom.

Usage

When to use Card, what its props are for, and the choices it leaves to you.

When to use

A card puts an edge around content that belongs together and gives it a place for its own controls. It has five slots: a header of title and extra, a cover, the body, a row of actions along the bottom, and a footer below them. All but the body are optional.
  • One object shown as a tile: a project, a plan, a product, a repository. A grid of them scans as a set.
  • A dashboard panel: one metric or chart, named by its title, with a time range switcher in extra.
  • A section of a long form or settings page, where the edge groups the fields that answer one question.
  • A summary that leads somewhere: a cover, a name, two lines of description and one link.
Use something else when
  • There is no title and no actions. A plain div on bg-container with the theme's padding and radius does the same job.
  • The items are rows, not tiles. Use a list. A card per row gives every row its own border and loses the column alignment a list gives you.
  • It takes the whole page. Use a Modal when it interrupts, and a page section when it does not.
  • The structure is inside one card. Try type="inner" or type="inset" before nesting a card in a card. Two edges a few pixels apart look like a rendering bug.

Chrome: variant, size and type

Three props set the look before any content goes in, and each works on its own: variant is the edge, size the padding, and type the structure.
Variant
  • Outlined cards rest on a shadow, and borderless cards are flat. variant="outlined" (the default) has a soft shadow and no visible border, and variant="borderless" has neither. hoverable lifts either one a step.
  • Use outlined when the card stands on the page background, and borderless inside a surface that already has an edge, like a Modal, a Drawer or another card.
  • Pick one variant per view and keep it.
  • To change a resting shadow, use a scoped class like [&.ant-card-bordered]:shadow-<key>, because a plain shadow-* in className does not replace it. An outlined card carries ant-card-bordered, and a borderless one carries no class of its own.
Size
  • Two sizes. size takes small and the default medium. middle and default still work as older names for medium, and there is no large.
  • Use small for dense surfaces: a sidebar, a stat tile, a grid of many. It tightens the header and body padding.
  • A ConfigProvider with componentSize sets the size for every card inside it, which suits a dense region.
Type
  • type="inner" is for a card inside a card. It gives the header a lighter fill, so the card reads as a section of its parent. Add variant="borderless" to sit it flush.
  • type="inset" puts the content on its own surface. The card gets a tinted ground, and the body, cover and actions sit on a raised surface inside it, with the header and the footer on the tint.
  • In dark mode the inset tint barely shows against the page background, so place inset cards on a container surface there. A cover or actions row shows a thin line where it meets the body.

Color and emphasis

color tints the card, and emphasis sets how strongly. default is a light tint with colored text, subtle a neutral ground with colored text, and strong a solid fill with white text. color takes antd's presets (blue, green, gold and the rest) or a palette from your theme (the default theme adds amber, emerald, teal, sky, indigo, violet, fuchsia, rose and grays like slate and zinc). A name with no ramp, like a hex, is ignored.
  • Check strong cards for contrast. White text on the solid fill falls below WCAG AA for 8 of the 20 hues in light mode and 16 in dark mode, with yellow the weakest. Keep strong for short or large text, and use default for body copy.
  • Give color a meaning, like a status or a category, and keep the same color for the same meaning across the page.
  • With type="inset", the color goes on the frame and the header, and the content keeps its white surface.
  • On a colored card, links in the header, extra and actions take the card's text color and an underline, and the header divider follows the text color too.

Shape

shape="squircle" needs corner-shape support. It bends the corners into a superellipse on twice the large radius. Browsers without corner-shape, like Safari today, keep the default corners.
  • The shape reaches the inset surface and the cover as well, so a squircle inset card stays consistent inside.
  • Pick one shape for every card in a view.
title and extra share one row, the title at the start and the extra at the end. The header appears only when one of them, or tabList, is set.
  • The title names the card. Keep it a short noun phrase that does not wrap next to its extra.
  • Keep extra to one thing: a link, a menu button, a range switcher. Three controls make a toolbar, which belongs in the body or above the card.
  • A link in extra should say where it goes (“All invoices”), not what it is (“More”), because it is read out of context.
  • The tab bar uses the kit's Tabs style. tabList puts a Tabs bar in the header, floating and neutral by default, at a size that matches the card. Control it with activeTabKey and onTabChange, or set defaultActiveTabKey. tabProps takes the kit's Tabs props, so { type: "line", color: "primary" } gives Ant Design's look and { size: "large" } its size.

Cover

cover renders above the body with no padding, so a full-width image meets the card's rounded corners. It takes any node, so a chart, a map or a gradient works too.
  • Give every cover in a row the same aspect ratio, so the bodies start at the same height across the grid.
  • A decorative image takes an empty alt. One that carries information the body does not repeat takes a real one.
  • A cover under a header has square top corners. The cover's top corners are rounded only when it is the first thing in the card.
  • A cover still shows while loading is on, so do not put content that is still loading there.

Actions, and their order

actions takes an array of nodes and renders them as equal cells along the bottom, split by thin lines. The array's order is the row's order from the start edge, so it mirrors in right-to-left layouts.
  • Use two or three. The cells split the width evenly, so with four only icons fit, and four unlabeled icons are a puzzle.
  • Put the most used action first and a destructive one last, or elsewhere, because the row has no room for a confirmation.
  • These act on the card's subject. A control for one item in the body goes beside that item, and a control that changes what the card shows goes in extra.
  • Use footer for buttons of different weight. actions makes every cell equal, which suits peers such as Edit, Share and Delete. A form's Cancel and Subscribe, one of them primary, go in footer.
  • Keep the same actions in the same order across every card in a set.
  • Every icon-only action needs a name. The Accessibility tab shows how.

Loading, against a Skeleton

loading replaces the body only. The header, cover and actions stay, so the card keeps its size when the data arrives.
  • Use it when the frame is known and only the content is in flight: the title is decided and the card's place on the page is reserved.
  • For a card that does not exist yet, render a Skeleton the card's height in its place, not a loading card with an empty title.
  • Do not nest the two. A Skeleton inside a loading card shows two of them.
  • Keep the actions unavailable while the body loads, or the card offers actions for something it has not shown. disabled on the card covers everything inside it.

Hoverable, and the whole-card link

hoverable lifts the card a step on hover. A lift tells the reader the card does something when clicked.
  • Set it only on a card that does something when clicked. A card that lifts and then ignores the click looks broken.
  • A whole-card click target needs a real link or button inside the card, not an onClick on the root. The usual shape is a link on the title, stretched over the card with a positioned pseudo-element, so the tab stop, the role and the URL stay on the link. The Accessibility tab covers the details.
  • One destination per card. A stretched link plus an actions row puts controls inside a control. If the card needs both, link the title only.
  • disabled blocks the keyboard too. It dims the card and sets inert, so buttons and links inside cannot be clicked, focused or read by a screen reader. A pointer-events-auto or opacity-100 in className still wins.

Card.Meta and Card.Grid

Import Card.Grid and Card.Meta from antd. The kit's Card does not include them.
  • Card.Meta lays out an avatar, a title and a description. Use it instead of building that layout by hand, so every card in a grid puts its name in the same place. Clamp the description, since it is the line that wraps.
  • Card.Grid splits one card's body into cells, drawn with inset shadows so the seams never double up. You set each cell's width.
  • hoverable is on by default for a grid cell, unlike a card. Pass hoverable={false} to turn it off for one cell.
  • When the tiles are separate objects, use separate cards in a Row and Col with a gutter. Do not clip a Row of cards. The gutter uses negative margins on the Row, so overflow-hidden cuts off the outer cards' edges.
  • Style parts with classNames. The keys are root, header, body, extra, title, actions and cover. headStyle and bodyStyle are deprecated, so use styles.header and styles.body.