Cards group related content and actions into a contained, scannable unit. They support media, headers, body text, and footers for flexible content layouts.
import {Card} from "@qualcomm-ui/react/card"Examples
Showcase
All card parts are optional. Combine them to fit the content you need to display.
This is a small card with media, header, body text, and a footer with actions.
<Card.Root className="w-72" variant="outline">
<Card.Media>
<Card.Avatar>
<Avatar.Content icon={User} />
</Card.Avatar>
</Card.Media>
<Card.Content>
<Card.Heading>
<Card.HeadingText>Card Title</Card.HeadingText>
<Card.SubheadingText>Subheading</Card.SubheadingText>
</Card.Heading>
<Card.SubheadingText>Paragraph Subheading</Card.SubheadingText>
<Card.ParagraphText>
This is a small card with media, header, body text, and a footer
with actions.
</Card.ParagraphText>
</Card.Content>
<Card.Footer>
<Card.Button variant="secondary">Cancel</Card.Button>
<Card.Button variant="primary">Confirm</Card.Button>
</Card.Footer>
</Card.Root>
Variants
The variant prop controls border and shadow styles.
A card with a border and background color.
A card with a border and subtle elevation.
A card with a subtle elevation and no border.
<Card.Root className="w-64" variant="outline">
<Card.Content>
<Card.Heading>
<Card.HeadingText>Outline</Card.HeadingText>
</Card.Heading>
<Card.ParagraphText>
A card with a border and background color.
</Card.ParagraphText>
</Card.Content>
</Card.Root>
<Card.Root className="w-64" variant="outline-elevated">
<Card.Content>
<Card.Heading>
<Card.HeadingText>Outline Elevated</Card.HeadingText>
</Card.Heading>
<Card.ParagraphText>
A card with a border and subtle elevation.
</Card.ParagraphText>
</Card.Content>
</Card.Root>
<Card.Root className="w-64" variant="elevated">
<Card.Content>
<Card.Heading>
<Card.HeadingText>Elevated</Card.HeadingText>
</Card.Heading>
<Card.ParagraphText>
A card with a subtle elevation and no border.
</Card.ParagraphText>
</Card.Content>
</Card.Root>
Actions
Two types of actions are supported in cards: Card.Button and Card.Link.
Cards can use links to navigate users to related content.
Cards can use buttons for primary and secondary actions.
<Card.Root className="w-64 self-start" variant="outline">
<Card.Content>
<Card.Heading>
<Card.HeadingText>Link Action</Card.HeadingText>
</Card.Heading>
<Card.ParagraphText>
Cards can use links to navigate users to related content.
</Card.ParagraphText>
</Card.Content>
<Card.Footer>
<Card.Link endIcon={ChevronRight}>Learn More</Card.Link>
</Card.Footer>
</Card.Root>
<Card.Root className="w-64" variant="outline">
<Card.Content>
<Card.Heading>
<Card.HeadingText>Button Actions</Card.HeadingText>
</Card.Heading>
<Card.ParagraphText>
Cards can use buttons for primary and secondary actions.
</Card.ParagraphText>
</Card.Content>
<Card.Footer>
<Card.Button variant="secondary">Cancel</Card.Button>
<Card.Button variant="primary">Confirm</Card.Button>
</Card.Footer>
</Card.Root>
Interactive
Set interactive on Card.Root to enable hover and pressed visual states on the content area. Use the render prop to make the root element to a <button> so screen readers know that the element is interactive.
WARNING
Interactive cards must not contain buttons, links, or input fields. React will yell at you if you nest interactive elements. Install the QUI React ESLint Plugin to enforce this in your project.
<Card.Root
className="w-64"
interactive
render={<button />}
variant="elevated"
>
<Card.Content>
<Card.Heading>
<Card.HeadingText>Interactive Card</Card.HeadingText>
</Card.Heading>
<Card.ParagraphText>
Hover or press this card to see the interactive states.
</Card.ParagraphText>
</Card.Content>
</Card.Root>
Media
Use Card.Media to display an image or other visual content at the top of the card.

<Card.Root className="w-64" variant="outline">
<Card.Media>
<img
alt="Qualcomm automotive technology"
className="h-40 w-full"
src="https://react.qui.qualcomm.com/images/auto-vertical-1.png"
/>
</Card.Media>
<Card.Content>
<Card.Heading>
<Card.HeadingText>Automotive Platform</Card.HeadingText>
<Card.SubheadingText>Next-gen connectivity</Card.SubheadingText>
</Card.Heading>
</Card.Content>
<Card.Footer>
<Card.Link endIcon={ChevronRight}>Learn More</Card.Link>
</Card.Footer>
</Card.Root>
Badge
Use Card.Badge to place a badge within the card.
Unleash your masterpiece with ultra-premium performance, multi-day battery life, and blazing AI processing power.
<Card.Root className="w-72" variant="outline">
<Card.Badge>
<Badge emphasis="brand">NEW</Badge>
</Card.Badge>
<Card.Content>
<Card.Heading>
<Card.HeadingText>Snapdragon X2 Elite</Card.HeadingText>
<Card.SubheadingText>
A legendary leap in performance
</Card.SubheadingText>
</Card.Heading>
<Card.ParagraphText>
Unleash your masterpiece with ultra-premium performance, multi-day
battery life, and blazing AI processing power.
</Card.ParagraphText>
</Card.Content>
<Card.Footer>
<Card.Link endIcon={ChevronRight}>Learn More</Card.Link>
</Card.Footer>
</Card.Root>
Alignment
Set alignment on Card.Root to control horizontal positioning of heading and footer content. Defaults to start.
Toggle between start and center alignment to see how heading and footer content repositions.
<Card.Root alignment={alignment} className="w-80" variant="outline">
<Card.Content>
<Card.Heading>
<Card.EyebrowText>Eyebrow</Card.EyebrowText>
<Card.HeadingText>Card Title</Card.HeadingText>
<Card.SubheadingText>Subheading</Card.SubheadingText>
</Card.Heading>
<Card.ParagraphText>
Toggle between start and center alignment to see how heading and
footer content repositions.
</Card.ParagraphText>
</Card.Content>
<Card.Footer>
<Card.Button variant="secondary">Cancel</Card.Button>
<Card.Button variant="primary">Confirm</Card.Button>
</Card.Footer>
</Card.Root>
Sizes
Cards support sm, md, and lg sizes that control internal spacing and typography.
Resize this card using the controls below to see how spacing and typography scale across sizes.
<Card.Root size={size} style={{width}} variant="outline">
<Card.Media>
<Card.Avatar>
<Avatar.Content icon={User} />
</Card.Avatar>
</Card.Media>
<Card.Content>
<Card.Heading>
<Card.EyebrowText>Eyebrow</Card.EyebrowText>
<Card.HeadingText>Card Title</Card.HeadingText>
</Card.Heading>
<Card.SubheadingText>Subheading</Card.SubheadingText>
<Card.ParagraphText>
Resize this card using the controls below to see how spacing and
typography scale across sizes.
</Card.ParagraphText>
</Card.Content>
<Card.Footer>
<Card.Button variant="secondary">Cancel</Card.Button>
<Card.Button variant="primary">Confirm</Card.Button>
</Card.Footer>
</Card.Root>
Explorer
A brief description that provides additional context about this card.
Learn moreComponent Anatomy
Hover to highlight, click to view API
API
<Card.Root>
| 'start'
| 'center'
'ltr' | 'rtl'
booleantrue, the root of the card will be styled as a button with interactive
states.| ReactElement
| ((
props: object,
) => ReactElement)
| 'sm'
| 'md'
| 'lg'
| 'outline'
| 'outline-elevated'
| 'elevated'
className'qui-card__root'data-alignment| 'start'
| 'center'
data-card-part'root'data-interactivedata-size| 'sm'
| 'md'
| 'lg'
data-variant| 'outline'
| 'outline-elevated'
| 'elevated'
<Card.Media>
<div> element by default.className'qui-card__media'data-card-part'media'data-padding'sm' | 'lg'
data-size| 'sm'
| 'md'
| 'lg'
<Card.Avatar>
<div> element by default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-card__avatar'data-card-part'avatar'data-size'xl'<Card.Badge>
<div> element by default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-card__badge'data-card-part'badge'<Card.Content>
<div> element by default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-card__content'data-alignment| 'start'
| 'center'
data-card-part'content'data-size| 'sm'
| 'md'
| 'lg'
<Card.Heading>
<div> element by default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-card__heading'data-alignment| 'start'
| 'center'
data-card-part'heading'data-size| 'sm'
| 'md'
| 'lg'
<Card.EyebrowText>
<span> element by default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-card__eyebrow-text'data-card-part'eyebrow-text'data-size| 'sm'
| 'md'
| 'lg'
<Card.HeadingText>
<div> element by default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-card__heading-text'data-card-part'heading-text'data-size| 'sm'
| 'md'
| 'lg'
<Card.MenuTrigger>
<div> element by default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-card__menu-trigger'data-card-part'menu-trigger'data-size| 'sm'
| 'md'
| 'lg'
<Card.SubheadingText>
<div> element by
default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-card__subheading-text'data-card-part'subheading-text'data-size| 'sm'
| 'md'
| 'lg'
<Card.ParagraphText>
<p> element by default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-card__paragraph-text'data-card-part'paragraph-text'data-size| 'sm'
| 'md'
| 'lg'
<Card.Footer>
<div> element by default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-card__footer'data-alignment| 'start'
| 'center'
data-card-part'footer'data-size| 'sm'
| 'md'
| 'lg'
<Card.Button>
<button> element by default.className'qui-card__button'data-card-part'button'data-size| 'sm'
| 'md'
| 'lg'
<Card.Link>
<a> element by default.'ltr' | 'rtl'
booleantrue, pointer/focus
events are blocked, and the link is visually dimmed.| LucideIcon
| ReactNode
LucideIcon, the size will automatically match the size prop.
Supply as a ReactElement for additional customization.boolean| ReactElement
| ((
props: object,
) => ReactElement)
| LucideIcon
| ReactNode
LucideIcon,
the size will automatically match the size prop. Supply as a
ReactElement for additional customization.| 'primary'
| 'secondary'
className'qui-card__link'data-card-part'link'data-size| 'xs'
| 'sm'
| 'md'
| 'lg'
| 'xl'
| 'xxl'
<div>element by default.