Skeleton
Skeleton은 콘텐츠 로딩 중에 플레이스홀더를 표시하는 컴포넌트입니다. 실제 레이아웃 구조를 미리 보여 레이아웃 시프트를 방지하고 체감 속도를 높입니다.
3
Variants
2
Animations
Count
Multi-line
Pure
React
Playground
Preview
text × 3pulse
Variant
Animation
Count
<Skeleton count={3} />Variants
Text
텍스트 행 플레이스홀더, 둥근 모서리와 비례 행 높이
Circular
아바타, 아이콘용 원형 플레이스홀더
Rectangular
이미지, 카드 영역용 직사각형 플레이스홀더
Features
Animation
2가지 애니메이션입니다. pulse는 밝기 펄스, wave는 좌→우 시머 효과입니다.
pulse
wave
false (static)
<Skeleton animation="pulse" />
<Skeleton animation="wave" />
<Skeleton animation={false} />Composition
여러 Skeleton을 조합하여 카드, 리스트 등 복잡한 레이아웃을 재현할 수 있습니다.
<div className="flex items-start gap-4">
<Skeleton variant="circular" />
<div className="flex-1 space-y-2">
<Skeleton className="w-1/3" />
<Skeleton />
<Skeleton className="w-4/5" />
</div>
</div>Count
count으로 텍스트 행을 자동 생성합니다. 마지막 행은 짧고, 각 행은 자연스러운 너비 변화가 있습니다.
count={3}
count={5} animation="wave"
<Skeleton count={3} />
<Skeleton count={5} animation="wave" />Loading Wrapper
loading prop으로 조건부 렌더링합니다. true이면 Skeleton 표시, false이면 children을 렌더링합니다.
loading=true
JH
loading=false<Skeleton loading={isLoading} variant="circular">
<Avatar src={user.avatar} />
</Skeleton>Custom Sizing
width, height, radius prop으로 정밀한 크기 조정이 가능합니다.
<Skeleton width={200} height={12} />
<Skeleton variant="circular" width={64} height={64} />
<Skeleton variant="rectangular" height={120} radius={16} />API
Component Structure
Skeleton— Pure React스탠드얼론 컴포넌트, 서브 컴포넌트 없음
Props
variant"text""text" | "circular" | "rectangular"형태 variant (text: 둥근 행, circular: 원형, rectangular: 직사각형)
animation"pulse""pulse" | "wave" | false애니메이션 (pulse: 밝기 페이드, wave: 시머, false: 정적)
countundefinednumber텍스트 행 수 (text variant 전용, 자동 너비 변화 포함)
loadingundefinedboolean조건부 로딩 (true: Skeleton 표시, false: children 렌더링)
widthundefinedstring | number커스텀 너비
heightundefinedstring | number커스텀 높이
radiusundefinedstring | number커스텀 border-radius
childrenundefinedReactNodeloading이 false일 때 렌더링할 콘텐츠
classNameundefinedstring추가 CSS 클래스
| Name | Type | Default | Description |
|---|---|---|---|
variant | "text" | "circular" | "rectangular" | "text" | 형태 variant (text: 둥근 행, circular: 원형, rectangular: 직사각형) |
animation | "pulse" | "wave" | false | "pulse" | 애니메이션 (pulse: 밝기 페이드, wave: 시머, false: 정적) |
count | number | undefined | 텍스트 행 수 (text variant 전용, 자동 너비 변화 포함) |
loading | boolean | undefined | 조건부 로딩 (true: Skeleton 표시, false: children 렌더링) |
width | string | number | undefined | 커스텀 너비 |
height | string | number | undefined | 커스텀 높이 |
radius | string | number | undefined | 커스텀 border-radius |
children | ReactNode | undefined | loading이 false일 때 렌더링할 콘텐츠 |
className | string | undefined | 추가 CSS 클래스 |
Anatomy
Text
1
Circular
2
Rectangular
3
Wave Overlay
W
1
Text
h-4 rounded-md
2
Circular
w-10 h-10
3
Rectangular
w-full h-24
W
Wave
shimmer overlay
Best Practices
✓
권장
- ✓실제 콘텐츠 레이아웃에 맞는 형태와 크기를 사용합니다
- ✓아바타는 circular, 텍스트는 text, 이미지는 rectangular를 사용합니다
- ✓페이지 초기 표시 시 loading.tsx와 함께 사용합니다
✕
지양
- ✕실제 레이아웃과 크게 다른 Skeleton을 사용하지 않습니다
- ✕즉시 표시되는 데이터에는 Skeleton을 사용하지 않습니다. 불필요한 깜빡임의 원인이 됩니다.
- ✕불확정한 대기에는 Skeleton 대신 Spinner를 사용합니다
Accessibility
ARIA / WCAG
aria-hidden="true"자동 부여- 장식 요소로 스크린 리더에서 숨김 처리
- 부모 컨테이너에
aria-busy설정 권장 prefers-reduced-motion지원