Flexible container component for grouping related content and actions.
Import
import { Card } from "heroui-solid";Usage
Become an Acme Creator!
Visit the Acme Creator Hub to sign up today and start earning credits from your fans and followers.
import { CircleDollar } from "gravity-icons-solid"
import { Card, Link } from "heroui-solid"
export function Default() {
return (
<Card class="w-[400px]">
<CircleDollar
aria-label="Dollar sign icon"
class="text-accent size-6"
role="img"
/>
<Card.Header>
<Card.Title>Become an Acme Creator!</Card.Title>
<Card.Description>
Visit the Acme Creator Hub to sign up today and start earning credits
from your fans and followers.
</Card.Description>
</Card.Header>
<Card.Footer>
<Link
aria-label="Go to Acme Creator Hub (opens in new tab)"
href="https://heroui.com"
rel="noopener noreferrer"
target="_blank"
>
Creator Hub
<Link.Icon aria-hidden="true" />
</Link>
</Card.Footer>
</Card>
)
}Anatomy
Import the Card component and access all parts using dot notation.
import { Card } from "heroui-solid";
export default () => (
<Card>
<Card.Header>
<Card.Title />
<Card.Description />
</Card.Header>
<Card.Content />
<Card.Footer />
</Card>
);Variants
Cards come in semantic variants that describe their prominence level rather than specific visual styles. This allows themes to interpret them differently:
Transparent
Minimal prominence with transparent background
Use for less important content or nested cards
Default
Standard card appearance (bg-surface)
The default card variant for most use cases
Secondary
Medium prominence (bg-surface-secondary)
Use to draw moderate attention
Tertiary
Higher prominence (bg-surface-tertiary)
Use for primary or featured content
import { Card } from "heroui-solid"
export function Variants() {
return (
<div class="flex flex-col gap-4">
<Card class="w-[320px]" variant="transparent">
<Card.Header>
<Card.Title>Transparent</Card.Title>
<Card.Description>
Minimal prominence with transparent background
</Card.Description>
</Card.Header>
<Card.Content>
<p>Use for less important content or nested cards</p>
</Card.Content>
</Card>
<Card class="w-[320px]" variant="default">
<Card.Header>
<Card.Title>Default</Card.Title>
<Card.Description>
Standard card appearance (bg-surface)
</Card.Description>
</Card.Header>
<Card.Content>
<p>The default card variant for most use cases</p>
</Card.Content>
</Card>
<Card class="w-[320px]" variant="secondary">
<Card.Header>
<Card.Title>Secondary</Card.Title>
<Card.Description>
Medium prominence (bg-surface-secondary)
</Card.Description>
</Card.Header>
<Card.Content>
<p>Use to draw moderate attention</p>
</Card.Content>
</Card>
<Card class="w-[320px]" variant="tertiary">
<Card.Header>
<Card.Title>Tertiary</Card.Title>
<Card.Description>
Higher prominence (bg-surface-tertiary)
</Card.Description>
</Card.Header>
<Card.Content>
<p>Use for primary or featured content</p>
</Card.Content>
</Card>
</div>
)
}transparent- Minimal prominence, transparent background (great for nested cards)default- Standard card for most use casessecondary- Medium prominence to draw moderate attentiontertiary- Higher prominence for important content
Horizontal Layout

Become an ACME Creator!
Lorem ipsum dolor sit amet consectetur. Sed arcu donec id aliquam dolor sed amet faucibus etiam.
import { Button, Card, CloseButton } from "heroui-solid"
export function Horizontal() {
return (
<Card class="w-full items-stretch md:flex-row">
<div class="relative h-[120px] w-[120px] shrink-0 overflow-hidden rounded-2xl">
<img
alt="Cherries"
class="pointer-events-none absolute inset-0 h-full w-full scale-125 object-cover select-none"
loading="lazy"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/cherries.jpeg"
/>
</div>
<div class="flex flex-1 flex-col gap-3">
<Card.Header class="gap-1">
<Card.Title class="pr-8">Become an ACME Creator!</Card.Title>
<Card.Description>
Lorem ipsum dolor sit amet consectetur. Sed arcu donec id aliquam
dolor sed amet faucibus etiam.
</Card.Description>
<CloseButton
aria-label="Close banner"
class="absolute top-3 right-3"
/>
</Card.Header>
<Card.Footer class="mt-auto flex w-full items-center justify-between gap-3">
<div class="flex flex-col">
<span class="text-sm font-medium text-foreground">
Only 10 spots
</span>
<span class="text-xs text-muted">Submission ends Oct 10.</span>
</div>
<Button>Apply Now</Button>
</Card.Footer>
</div>
</Card>
)
}With Avatar

Indie Hackers
148 members

AI Builders
362 members
import { Avatar, Card } from "heroui-solid"
export function WithAvatar() {
return (
<div class="flex flex-wrap gap-4">
<Card class="w-[200px] gap-2">
<img
alt="Indie Hackers community"
class="pointer-events-none aspect-square w-14 rounded-2xl object-cover select-none"
loading="lazy"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/demo1.jpg"
/>
<Card.Header>
<Card.Title>Indie Hackers</Card.Title>
<Card.Description>148 members</Card.Description>
</Card.Header>
<Card.Footer class="flex gap-2">
<Avatar aria-label="Martha's profile picture" class="size-5">
<Avatar.Image
alt="Martha's avatar"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/red.jpg"
/>
<Avatar.Fallback class="text-xs">IH</Avatar.Fallback>
</Avatar>
<span class="text-xs">By Martha</span>
</Card.Footer>
</Card>
<Card class="w-[200px] gap-2">
<img
alt="AI Builders community"
class="pointer-events-none aspect-square w-14 rounded-2xl object-cover select-none"
loading="lazy"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/demo2.jpg"
/>
<Card.Header>
<Card.Title>AI Builders</Card.Title>
<Card.Description>362 members</Card.Description>
</Card.Header>
<Card.Footer class="flex gap-2">
<Avatar aria-label="John's profile picture" class="size-5">
<Avatar.Image
alt="John's avatar - blue themed"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/blue.jpg"
/>
<Avatar.Fallback class="text-xs">B</Avatar.Fallback>
</Avatar>
<span class="text-xs">By John</span>
</Card.Footer>
</Card>
</div>
)
}With Images

Become an ACME Creator!
Lorem ipsum dolor sit amet consectetur. Sed arcu donec id aliquam dolor sed amet faucibus etiam.
You can now withdraw on crypto
Add your wallet in settings to withdraw
Indie Hackers
148 members
AI Builders
362 members
NEO
Home Robot

Bridging the Future
Today, 6:30 PM

Avocado Hackathon
Wed, 4:30 PM

Sound Electro | Beyond art
Fri, 8:00 PM
import { CircleDollar } from "gravity-icons-solid"
import { Avatar, Button, Card, CloseButton, Link } from "heroui-solid"
export function WithImages() {
return (
<div class="flex w-full items-center justify-center">
<div class="grid w-full max-w-2xl grid-cols-12 gap-4 p-4">
{/* Row 1: Large Product Card - Available Soon */}
<Card class="col-span-12 flex h-auto min-h-[152px] flex-col sm:flex-row">
<div class="relative h-[140px] w-full shrink-0 overflow-hidden rounded-2xl sm:h-[120px] sm:w-[120px]">
<img
alt="Cherries"
class="pointer-events-none absolute inset-0 h-full w-full scale-125 object-cover select-none"
loading="lazy"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/cherries.jpeg"
/>
</div>
<div class="flex flex-1 flex-col gap-3">
<Card.Header class="gap-1">
<Card.Title class="pr-8">Become an ACME Creator!</Card.Title>
<Card.Description>
Lorem ipsum dolor sit amet consectetur. Sed arcu donec id
aliquam dolor sed amet faucibus etiam.
</Card.Description>
<CloseButton
aria-label="Close banner"
class="absolute top-3 right-3"
/>
</Card.Header>
<Card.Footer class="mt-auto flex w-full flex-col items-start gap-3 sm:flex-row sm:items-center sm:justify-between">
<div class="flex flex-col">
<span class="text-sm font-medium text-foreground">
Only 10 spots
</span>
<span class="text-xs text-muted">Submission ends Oct 10.</span>
</div>
<Button class="w-full sm:w-auto">Apply Now</Button>
</Card.Footer>
</div>
</Card>
{/* Row 2 */}
<div class="col-span-12 grid grid-cols-12 gap-4">
{/* Left Column */}
<div class="col-span-12 grid grid-cols-12 gap-4 lg:col-span-6">
{/* Top Card */}
<Card class="col-span-12">
<div class="absolute top-3 right-3 z-10">
<CloseButton aria-label="Close notification" />
</div>
<Card.Header class="gap-3">
<CircleDollar
aria-label="Dollar sign icon"
class="text-primary size-8 shrink-0"
role="img"
/>
<div class="flex flex-col gap-1">
<span class="text-xs font-medium text-muted uppercase">
PAYMENT
</span>
<Card.Title class="pr-8 text-sm sm:text-base">
You can now withdraw on crypto
</Card.Title>
<Card.Description class="text-xs sm:text-sm">
Add your wallet in settings to withdraw
</Card.Description>
</div>
</Card.Header>
<Card.Footer>
<Link
aria-label="Go to settings"
href="#"
rel="noopener noreferrer"
>
Go to settings
<Link.Icon aria-hidden="true" />
</Link>
</Card.Footer>
</Card>
{/* Bottom cards */}
<div class="col-span-12 grid grid-cols-12 gap-4">
{/* Left Card */}
<Card class="col-span-12 gap-2 sm:col-span-6">
<Card.Header>
<Avatar class="size-[56px] rounded-xl">
<Avatar.Image
alt="Demo 1"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/demo1.jpg"
/>
<Avatar.Fallback>JK</Avatar.Fallback>
</Avatar>
</Card.Header>
<Card.Content class="mt-1">
<p class="text-sm leading-4 font-medium">Indie Hackers</p>
<p class="text-xs text-muted">148 members</p>
</Card.Content>
<Card.Footer class="flex items-center gap-2">
<Avatar class="size-4">
<Avatar.Image
alt="John"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/red.jpg"
/>
<Avatar.Fallback>JK</Avatar.Fallback>
</Avatar>
<p class="text-xs text-muted">By John</p>
</Card.Footer>
</Card>
{/* Right Card */}
<Card class="col-span-12 gap-2 sm:col-span-6">
<Card.Header>
<Avatar class="size-[56px] rounded-xl">
<Avatar.Image
alt="Demo 2"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/demo2.jpg"
/>
<Avatar.Fallback>AB</Avatar.Fallback>
</Avatar>
</Card.Header>
<Card.Content class="mt-1">
<p class="text-sm leading-4 font-medium">AI Builders</p>
<p class="text-xs text-muted">362 members</p>
</Card.Content>
<Card.Footer class="flex items-center gap-2">
<Avatar class="size-4">
<Avatar.Image
alt="John"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/blue.jpg"
/>
<Avatar.Fallback>M</Avatar.Fallback>
</Avatar>
<p class="text-xs text-muted">By Martha</p>
</Card.Footer>
</Card>
</div>
</div>
{/* Right Column */}
<Card class="col-span-12 min-h-[200px] overflow-hidden rounded-3xl lg:col-span-6">
{/* Background image */}
<img
alt="NEO Home Robot"
aria-hidden="true"
class="absolute inset-0 h-full w-full object-cover"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/neo2.jpeg"
/>
{/* Header */}
<Card.Header class="z-10 text-white">
<Card.Title class="text-xs font-semibold tracking-wide text-black/70">
NEO
</Card.Title>
<Card.Description class="text-sm leading-5 font-medium text-black/50">
Home Robot
</Card.Description>
</Card.Header>
{/* Footer */}
<Card.Footer class="z-10 mt-auto flex items-center justify-between">
<div>
<div class="text-sm font-medium text-black">Available soon</div>
<div class="text-xs text-black/60">Get notified</div>
</div>
<Button class="bg-white text-black" size="sm" variant="tertiary">
Notify me
</Button>
</Card.Footer>
</Card>
</div>
{/* Row 3 */}
<div class="col-span-12 grid grid-cols-12 gap-4">
{/* Left Column: Card */}
<Card class="relative col-span-12 h-[250px] sm:h-[300px] md:col-span-8 md:h-[350px]">
<img
alt="NEO Home Robot"
aria-hidden="true"
class="absolute inset-0 h-full w-full object-cover"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/neo1.jpeg"
/>
<Card.Footer class="z-10 mt-auto flex items-end justify-between">
<div>
<div class="text-base font-medium text-black sm:text-lg">
NEO
</div>
<div class="text-xs font-medium text-black/50 sm:text-sm">
$499/m
</div>
</div>
<Button class="bg-white text-black" size="sm" variant="tertiary">
Get now
</Button>
</Card.Footer>
</Card>
{/* Right Column: Cards Stack */}
<div class="col-span-12 flex flex-col gap-2 md:col-span-4 md:justify-between md:gap-0 md:py-2">
{/* 1 */}
<Card class="flex flex-row gap-3 p-1" variant="transparent">
<img
alt="Futuristic Robot"
class="aspect-square h-16 w-16 shrink-0 rounded-xl object-cover select-none sm:h-20 sm:w-20"
loading="lazy"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/robot1.jpeg"
/>
<div class="flex flex-1 flex-col justify-center gap-1">
<Card.Title class="text-sm">Bridging the Future</Card.Title>
<Card.Description class="text-xs">
Today, 6:30 PM
</Card.Description>
</div>
</Card>
{/* 2 */}
<Card class="flex flex-row gap-3 p-1" variant="transparent">
<img
alt="Avocado"
class="aspect-square h-16 w-16 shrink-0 rounded-xl object-cover select-none sm:h-20 sm:w-20"
loading="lazy"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/avocado.jpeg"
/>
<div class="flex flex-1 flex-col justify-center gap-1">
<Card.Title class="text-sm">Avocado Hackathon</Card.Title>
<Card.Description class="text-xs">
Wed, 4:30 PM
</Card.Description>
</div>
</Card>
{/* 3 */}
<Card class="flex flex-row gap-3 p-1" variant="transparent">
<img
alt="Sound Electro event"
class="aspect-square h-16 w-16 shrink-0 rounded-xl object-cover select-none sm:h-20 sm:w-20"
loading="lazy"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/oranges.jpeg"
/>
<div class="flex flex-1 flex-col justify-center gap-1">
<Card.Title class="text-sm">
Sound Electro | Beyond art
</Card.Title>
<Card.Description class="text-xs">
Fri, 8:00 PM
</Card.Description>
</div>
</Card>
</div>
</div>
</div>
</div>
)
}With Form
Login
Enter your credentials to access your account
import { Button, Card, Form, Input, Label, Link, TextField } from "heroui-solid"
export function WithForm() {
const onSubmit = (event: SubmitEvent) => {
event.preventDefault()
alert("Form submitted successfully!")
}
return (
<Card class="w-full max-w-md">
<Card.Header>
<Card.Title>Login</Card.Title>
<Card.Description>
Enter your credentials to access your account
</Card.Description>
</Card.Header>
<Form onSubmit={onSubmit}>
<Card.Content>
<div class="flex flex-col gap-4">
<TextField name="email">
<Label>Email</Label>
<Input
placeholder="email@example.com"
type="email"
variant="secondary"
/>
</TextField>
<TextField name="password">
<Label>Password</Label>
<Input
placeholder="••••••••"
type="password"
variant="secondary"
/>
</TextField>
</div>
</Card.Content>
<Card.Footer class="mt-4 flex flex-col gap-2">
<Button fullWidth type="submit">
Sign In
</Button>
<Link class="text-center text-sm" href="#">
Forgot password?
</Link>
</Card.Footer>
</Form>
</Card>
)
}Accessibility
import { Card } from "heroui-solid";
import { cardVariants } from "heroui-solid";
// Semantic markup
<Card role="article" aria-labelledby="card-title">
<Card.Header>
<Card.Title id="card-title">Article Title</Card.Title>
</Card.Header>
</Card>
// Interactive cards
<a class={cardVariants().base()} href="/details" aria-label="View product details">
<Card.Title>Product Name</Card.Title>
</a>Related Components
- Surface: Base container surface
- Avatar: Display user profile images (not ported yet)
- Form: Form validation and submission handling (not ported yet)
Styling
Component Customization
<Card class="border-2 border-blue-500 bg-gradient-to-r from-blue-50 to-purple-50">
<Card.Header>
<Card.Title class="text-blue-900">Custom Styled Card</Card.Title>
<Card.Description class="text-blue-700">Custom colors applied</Card.Description>
</Card.Header>
<Card.Content>
<p class="text-blue-800">Content with custom styling</p>
</Card.Content>
</Card>CSS Variable Overrides
/* Override specific variants */
.card--secondary {
@apply bg-gradient-to-br from-blue-50 to-purple-50;
}
/* Custom element styles */
.card__title {
@apply text-xl font-bold;
}CSS Classes
Card uses BEM naming for predictable styling (View source styles):
Base Classes
.card- Base container with padding and border.card__header- Header section container.card__title- Title with base font size and weight.card__description- Muted description text.card__content- Flexible content container.card__footer- Footer with row layout
Variant Classes
.card--transparent- Minimal prominence, transparent background.card--default- Standard appearance (default).card--secondary- Medium prominence.card--tertiary- Higher prominence
API Reference
Card
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "transparent" | "default" | "secondary" | "tertiary" | "default" | Semantic variant indicating prominence level |
class | string | - | Additional CSS classes |
children | JSX.Element | - | Card content |
as | ValidComponent | "div" | Overrides the default DOM element (Kobalte polymorphic) |
Card.Header
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes |
children | JSX.Element | - | Header content |
Card.Title
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes |
children | JSX.Element | - | Title content (renders as h3) |
Card.Description
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes |
children | JSX.Element | - | Description content (renders as p) |
Card.Content
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes |
children | JSX.Element | - | Main content |
Card.Footer
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes |
children | JSX.Element | - | Footer content |
Differences from HeroUI React
- Use
classinstead ofclassName; the element type is overridden with Kobalte's polymorphicasprop instead of React'srenderprop. - The "With Avatar" and "With Images" examples from the official docs are omitted —
they rely on
AvatarandCloseButton, which aren't ported yet. - All parts accept
asfor custom elements (e.g.<Card.Title as="h2">).
Last updated: 7/19/26, 3:27 AM

