Card
surface 컨테이너 프리미티브 — emphasis(outlined·filled·elevated) × function(static·clickable)와 media/header/body/footer 슬롯. 풍부함은 prop이 아니라 시스템 재료 조립으로.
마지막 업데이트 2026-06-14
한눈에#
카드 표면(border·radius·background)의 단일 소스. emphasis로 깊이를, 슬롯으로 구조를 잡고, 풍부함은 Badge·Progress 같은 시스템 재료 조립으로 표현합니다 — 표면을 손수 그리지 않습니다.
- emphasis 3종
- static · clickable
- media 슬롯
- Flutter 패리티
같은 골격, 다른 깊이 — outlined(기본) · filled · elevated
사용 시점#
관련 정보·행동을 하나의 표면으로 묶을 때 씁니다. 클릭 동작 방식이 카드의 성격을 가릅니다.
권장 — 이렇게 쓰세요
지양 — 이러지 마세요
환경과 권한을 한 카드에서 관리합니다.
묶기 — 관련 정보·행동을 한 표면에 — 요약·설정 그룹
과한 표면 — 한 줄·단일 값엔 표면이 과합니다 — 그냥 텍스트로 충분합니다
전체 클릭 — 카드 전체가 하나의 목적지면 interactive
카드 전체가 링크인데 내부 버튼이 충돌합니다.
중첩 금지 — clickable 카드 안에 독립 버튼을 넣으면 클릭이 충돌합니다 — 대신 static을 쓰세요
해부#
실물 카드 위에 치수 브래킷·색 패딩 영역으로 측정을 표기합니다 — 값이 바뀌면 함께 움직입니다(드리프트 0). 앰버 영역 = 패딩, 브래킷 = 그 치수, 코너 호 = 라운드, 우측 강조 = 보더.
지난주 대비 전환율 +8.2%
- 라운드
- 14px
radius.lg - 보더
- 1px
color.border - 본문 패딩
- 24px
space-6 - 헤더/푸터
- 16 · 24px
space-4 · space-6
변형 — emphasis#
깊이는 그림자가 아니라 표면으로. 기본 outlined(플랫)이고, filled는 톤 표면, elevated만 그림자를 씁니다 — elevated는 강조 한 곳에만 쓰세요. 그림자를 남발하면 위계가 평평해집니다.
색은 이름이 아니라 실제 표면 스와치로 확인하세요 — emphasis 3종이 같은 콘텐츠를 어떻게 다른 깊이로 만드는지.
- surface
color.surface- border
color.border
- surface
color.surface-container- border
transparent
- surface
color.surface- border
transparent
변형 — function#
static(기본)은 비대화 컨테이너, interactive는 카드 전체가 클릭 대상이 됩니다 — role="button"·키보드(Enter/Space)·포커스 링. 클릭형 카드 안에는 독립 인터랙티브 요소를 중첩하지 마세요(필요하면 static).
슬롯#
media(풀-블리드 상단) → header → 본문 → footer. 미디어는 라운드에 맞춰 클립되고 본문 패딩과 무관합니다.
footer엔 기본 행동을 모으되 primary 버튼은 하나만 두세요(나머지는 ghost) — 동등한 primary가 여럿이면 위계가 흩어집니다. 본문은 긴 문단보다 스캔 가능한 항목으로 정리하면 한눈에 읽힙니다.
4.5K 레티나 · 256GB SSD · 7색
두 가지 조립 어휘#
슬롯은 두 방식으로 채울 수 있고, 같은 표면·간격 토큰을 공유합니다.
- prop 슬롯 —
media·header·footerprop. 한 줄로 끝나는 간결한 정의에 적합합니다(하위호환 정본). - 컴파운드 슬롯 —
Card.Media·Card.Header·Card.Body·Card.Footer(서버 컴포넌트에선 평탄 이름CardMedia·CardHeader·CardBody·CardFooter). 슬롯에 다중 자식·복합 구조가 필요할 때, 또는 각 슬롯에className을 직접 매길 때 씁니다.
점 표기(Card.Header)와 평탄 이름(CardHeader)은 동일 함수입니다 — 클라이언트에선 Card.Header, MDX·RSC 같은 서버 경계에선 평탄 이름을 쓰세요(점 접근이 해석되지 않기 때문).
// prop 슬롯 — 간결
<Card header="배포 설정" footer={<Button>저장</Button>}>
환경과 권한을 한 카드에서 관리합니다.
</Card>
// 컴파운드 슬롯 — 슬롯별 다중 자식·className
<Card>
<Card.Header>
<Badge variant="primary">추천</Badge>
<h3>배포 설정</h3>
</Card.Header>
<Card.Body>환경과 권한을 한 카드에서 관리합니다.</Card.Body>
<Card.Footer><Button>저장</Button></Card.Footer>
</Card>
아래 레시피의 〈가격·플랜〉 카드가 컴파운드 슬롯으로 조립한 실제 예시입니다.
상태#
interactive 카드의 상호작용 상태는 그림자가 아니라 표면·보더로 표현합니다(:hover→surface-hover, :active→surface-pressed). :focus-visible은 2px 포커스 링. 의사클래스라 정적 문서에선 잘 안 보이니, 아래 카드에 직접 포커스/호버 해보세요.
레시피#
리치한 카드는 컴포넌트를 복잡하게 만들어서가 아니라 시스템 재료를 조립해서 만듭니다 — 표면은 Card, 나머지는 Badge·Progress·토큰입니다. 인라인 표면 0.
201,530원
- 목표 금액
- 300,000원
- 현재 구매확정한 금액
- 98,470원
플레이그라운드#
컨트롤로 props를 조작하면 미리보기와 코드가 실시간 갱신됩니다.
Card를 직접 조작해 보세요
속성·테마·토큰을 바꾸고 React·Flutter 코드를 확인하는 풀스크린 빌더로 엽니다.
플레이그라운드는 넓은 작업 영역이 필요해 웹·태블릿에서 편집할 수 있어요.
Props#
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
media | ReactNode | — | 풀-블리드 미디어 슬롯(상단) — bodyPadding 무관, overflow 클립. |
header | ReactNode | — | 상단 제목 행 — 미제공 시 미렌더. 컴파운드 대안: <CardHeader>. |
footer | ReactNode | — | 하단 행동 영역(주요 액션 등) — 미제공 시 미렌더. 컴파운드 대안: <CardFooter>. |
bodyPadding | boolean | — | 본문 패딩 적용(기본 true). 미디어/표 등은 false 로 풀-블리드. 컴파운드 슬롯(<CardBody>)을 직접 쓰면 무관 — 패딩은 슬롯이 소유한다. |
emphasis | 'outlined' | 'filled' | 'elevated' | — | 시각 강조 — outlined(기본)·filled(톤)·elevated(그림자). |
interactive | boolean | — | 카드 전체를 클릭 가능하게(호버/포커스/프레스 + 키보드 Enter/Space). a11y: 내부에 독립 인터랙티브 요소를 중첩하지 말 것 — 필요하면 static 카드를 사용. |
shadow | boolean | — | @deprecated emphasis="elevated"를 사용하세요. shadow=true는 elevated로 매핑됩니다. |
ref | Ref<HTMLDivElement> | — | 루트 <div>로 전달되는 ref (React 19 ref-as-prop) |
그 외 className·onClick 등 표준 <div> 속성은 루트로 그대로 전달됩니다(…rest).
토큰#
component 토큰 없이 semantic을 직접 소비합니다(신설 기준 §4 미충족).
| 속성 | 토큰 |
|---|---|
| 배경 (outlined/elevated) | color.surface |
| 배경 (filled) | color.surface-container |
| 보더 (outlined) | color.border |
| 라운드 | radius.lg |
| 그림자 (elevated) | shadow.md |
| 호버/프레스 (interactive) | color.surface-hover · color.surface-pressed |
| 포커스 링 | color.focus-ring |
| 패딩 | space.4 · space.6 |
접근성#
- 기본은 의미 중립
div— 문서 구조(헤딩 레벨)는 소비자가 책임지며, header 슬롯엔 필요 시h2/h3를 직접 넣습니다 interactive카드는role="button"+tabIndex=0+ Enter/Space 활성 +:focus-visible링. 클릭형 카드 안에 독립 인터랙티브 요소를 중첩하지 마세요 — 내부 버튼/링크가 필요하면 static 카드를 쓰세요(중첩 인터랙션 혼란 방지)- 상호작용 상태는 색 대비뿐 아니라 표면·보더·포커스 링으로 다중 신호를 줍니다
Flutter 패리티#
WDS Card는 Flutter WizCard와 동일 계약을 공유합니다 — 같은 emphasis(outlined/filled/elevated) · onTap(=웹 interactive, 포커스/키보드 동반) · media/header/footer 슬롯, 그리고 shadow→elevated 하위호환. RAG 소스 카드 KnowledgeCard(웹)도 Flutter WizKnowledgeCard와 1:1입니다.