Add the optional <twig:ui:Card:Action> inside the header to place an
action in the top corner of the card, such as a button or a badge.
<twig:ui:Cardclass="w-full max-w-sm">
<twig:ui:Card:Header>
<twig:ui:Card:Title>Notifications</twig:ui:Card:Title>
<twig:ui:Card:Description>You have 3 unread messages.</twig:ui:Card:Description>
<twig:ui:Card:Action>
<twig:ui:Buttonvariant="outline"size="sm">
<twig:ux:iconname="lucide:check-check"data-icon="inline-start" />
Mark all as read
</twig:ui:Button>
</twig:ui:Card:Action>
</twig:ui:Card:Header>
<twig:ui:Card:Content>
<p>Your team mentioned you in 3 conversations today.</p>
</twig:ui:Card:Content>
</twig:ui:Card>
With header border
The footer is separated from the content by default. To separate the header
too, add border-b; the matching padding is applied automatically.
Place an <img> as the first direct child for full-bleed media. The top
padding is removed and the corners are rounded automatically. Serve a
resized, compressed file and add loading="lazy" so the image does not slow
the page down.
<twig:ui:Cardclass="w-full max-w-sm">
<imgsrc="{{ 'media/home-hero.png'|imagine_filter('doc_demo') }}"alt="Preview of the HarmonyUI component library"loading="lazy"width="768"height="432"class="aspect-video w-full object-cover"
/>
<twig:ui:Card:Header>
<twig:ui:Card:Title>Design without friction</twig:ui:Card:Title>
<twig:ui:Card:Description>Ship polished interfaces with ready-made Twig components.</twig:ui:Card:Description>
</twig:ui:Card:Header>
<twig:ui:Card:Footer>
<twig:ui:Buttonvariant="outline"class="w-full">
Read the story
<twig:ux:iconname="lucide:arrow-right"data-icon="inline-end" />
</twig:ui:Button>
</twig:ui:Card:Footer>
</twig:ui:Card>
Sizes
The size prop scales the paddings and gaps of every section at once:
sm (12px), default (16px), lg (24px) and xl (32px). The sm size
also shrinks the title.
<divclass="grid w-full max-w-2xl gap-4 sm:grid-cols-2">
<twig:ui:Cardsize="sm">
<twig:ui:Card:Header>
<twig:ui:Card:Title>Small</twig:ui:Card:Title>
<twig:ui:Card:Description>12px spacing and a smaller title.</twig:ui:Card:Description>
</twig:ui:Card:Header>
<twig:ui:Card:Content>
<p>Compact, for dense layouts.</p>
</twig:ui:Card:Content>
</twig:ui:Card>
<twig:ui:Card>
<twig:ui:Card:Header>
<twig:ui:Card:Title>Default</twig:ui:Card:Title>
<twig:ui:Card:Description>16px spacing.</twig:ui:Card:Description>
</twig:ui:Card:Header>
<twig:ui:Card:Content>
<p>The size to reach for first.</p>
</twig:ui:Card:Content>
</twig:ui:Card>
<twig:ui:Cardsize="lg">
<twig:ui:Card:Header>
<twig:ui:Card:Title>Large</twig:ui:Card:Title>
<twig:ui:Card:Description>24px spacing.</twig:ui:Card:Description>
</twig:ui:Card:Header>
<twig:ui:Card:Content>
<p>Roomier, for standalone sections.</p>
</twig:ui:Card:Content>
</twig:ui:Card>
<twig:ui:Cardsize="xl">
<twig:ui:Card:Header>
<twig:ui:Card:Title>Extra large</twig:ui:Card:Title>
<twig:ui:Card:Description>32px spacing.</twig:ui:Card:Description>
</twig:ui:Card:Header>
<twig:ui:Card:Content>
<p>Generous, for hero content.</p>
</twig:ui:Card:Content>
</twig:ui:Card>
</div>
Custom spacing
The predefined sizes set the --card-spacing variable, so any other value
is one utility class away: override the variable on the root and every
section follows.
<twig:ui:Cardclass="w-full max-w-sm [--card-spacing:--spacing(10)]">
<twig:ui:Card:Header>
<twig:ui:Card:Title>Custom spacing</twig:ui:Card:Title>
<twig:ui:Card:Description>This card overrides the variable to 40px.</twig:ui:Card:Description>
</twig:ui:Card:Header>
<twig:ui:Card:Content>
<p>Use a predefined size when one fits; reach for the variable when it does not.</p>
</twig:ui:Card:Content>
</twig:ui:Card>
RTL
Set dir="rtl" on the root to render the card for right-to-left languages.
The default styles use logical properties, so the header action and text
alignment follow the reading direction.
<twig:ui:Carddir="rtl"class="w-full max-w-sm">
<twig:ui:Card:Header>
<twig:ui:Card:Title>ترقية خطتك</twig:ui:Card:Title>
<twig:ui:Card:Description>احصل على تحليلات متقدمة ومشاريع غير محدودة.</twig:ui:Card:Description>
<twig:ui:Card:Action>
<twig:ui:Buttonvariant="ghost"size="icon-sm"aria-label="إغلاق">
<twig:ux:iconname="lucide:x" />
</twig:ui:Button>
</twig:ui:Card:Action>
</twig:ui:Card:Header>
<twig:ui:Card:Content>
<p>تمت الإشارة إليك في ٣ محادثات اليوم.</p>
</twig:ui:Card:Content>
<twig:ui:Card:Footer>
<twig:ui:Buttonclass="w-full">ترقية</twig:ui:Button>
</twig:ui:Card:Footer>
</twig:ui:Card>
API Reference
<twig:ui:Card>
Prop
Type
Description
size
'sm' | 'default' | 'lg' | 'xl'
The spacing scale of the card. Defaults to default
as
string
The HTML tag to render. Defaults to div
Block
Description
content
The card sections: header, content and footer
<twig:ui:Card:Header>
Wraps the title, description and optional action. A column is reserved for
the action automatically when one is present.
Prop
Type
Description
as
string
The HTML tag to render. Defaults to div
Block
Description
content
The title, description and optional action
<twig:ui:Card:Title>
Prop
Type
Description
as
string
The HTML tag to render. Defaults to div
Block
Description
content
The card title
<twig:ui:Card:Description>
Prop
Type
Description
as
string
The HTML tag to render. Defaults to div
Block
Description
content
The card description
<twig:ui:Card:Action>
Placed in the top corner of the header, spanning the title and description
rows.
Prop
Type
Description
as
string
The HTML tag to render. Defaults to div
Block
Description
content
The action, usually a <twig:ui:Button> or a badge
<twig:ui:Card:Content>
Prop
Type
Description
as
string
The HTML tag to render. Defaults to div
Block
Description
content
The main content of the card
<twig:ui:Card:Footer>
Rendered as a muted band separated from the content by a border.
Prop
Type
Description
as
string
The HTML tag to render. Defaults to div
Block
Description
content
The footer content, usually actions or secondary text