CardHeader — spec¶
Synthesized from MUI
CardHeader. The structured header region of aCard— avatar/icon + title + subheader + optional trailing action. Distinct from a plain<Typography variant="h6">insideCardContentbecause it handles the avatar/action layout.
When to use¶
- Cards representing a person/entity (post by user, project by team).
- Cards with a top-level action (more menu, dismiss button).
- For text-only cards, use
<Typography>insideCardContentinstead.
Anatomy¶
┌─────────────────────────────────────────┐
│ [avatar] Title [⋮] │
│ Subheader │
└─────────────────────────────────────────┘
API¶
<Card>
<CardHeader
avatar={<Avatar src={user.avatarUrl} />}
title={user.name}
subheader="2시간 전 게시"
action={
<IconButton aria-label="더보기">
<MoreVertIcon />
</IconButton>
}
/>
<CardMedia component="img" image={post.image} />
<CardContent>...</CardContent>
</Card>
| Prop | Type | Default | Description |
|---|---|---|---|
avatar |
ReactNode |
— | Leading element (Avatar / Icon) |
title |
ReactNode |
— | Primary title (string or component) |
subheader |
ReactNode |
— | Sub-title (smaller, muted) |
action |
ReactNode |
— | Trailing right-aligned action (button/menu) |
disableTypography |
boolean |
false |
Skip default Typography wrapping |
titleTypographyProps |
TypographyProps |
— | Override title typography |
subheaderTypographyProps |
TypographyProps |
— | Override subheader typography |
States¶
Header itself is non-interactive. The action slot owns its states.
Tokens consumed¶
--font-size-heading-sm /* title — 16px */
--font-size-caption /* subheader — 12px */
--font-weight-semibold /* title */
--space-md /* horizontal padding */
--space-md-y /* vertical padding */
--color-fg-default
--color-fg-muted /* subheader */
Accessibility¶
- Title renders as
<span>by default — for semantic page hierarchy, use<Typography component="h2" variant="h6">as title prop instead of bare string. actionbutton needs an accessible name (aria-label="더보기").- Avatar
altshould be the person's name, not "avatar" or "user image".
Edge cases¶
- Long title — wraps; if you need ellipsis, set
titleTypographyProps={{ noWrap: true }}and ensure container width is bounded. - No avatar —
actionstill right-aligns; title/subheader fill the avatar's gap. Layout works fine. - Korean datetime in subheader — relative format "2시간 전" rather than absolute "2026-05-09 14:23". Cite
knowledge/i18n/korean-product-conventions.md.
Code example¶
function PostCard({ post, onMore, onLike }) {
return (
<Card>
<CardHeader
avatar={<Avatar src={post.author.avatarUrl}>{post.author.name[0]}</Avatar>}
title={post.author.name}
subheader={formatRelative(post.createdAt)} // "2시간 전"
action={
<IconButton aria-label={`${post.author.name}의 게시물 더보기`} onClick={onMore}>
<MoreVertIcon />
</IconButton>
}
/>
<CardMedia component="img" image={post.imageUrl} alt="" />
<CardContent>
<Typography variant="body2">{post.body}</Typography>
</CardContent>
<CardActions>
<IconButton aria-label="좋아요" onClick={onLike}>
<FavoriteIcon />
</IconButton>
</CardActions>
</Card>
);
}
Don't¶
- Don't put the entire card click handler on
CardHeader— split into specific actions. - Don't omit
aria-labelon theactionIconButton. - Don't use
CardHeaderfor a card without avatar/action —<Typography variant="h6">insideCardContentis lighter.
References¶
- MUI:
CardHeader