Skeleton

Import

<link rel="stylesheet" href="/guide/css/base/index.css" />
<link rel="stylesheet" href="/guide/css/components/skeleton.css" />

Live

Primitives

Title (100%)
Text (80%)
Avatar (60×60px)
Image (100%×180px)

Patterns

Card

Profile

Paragraph

Specs

요소 Height Width Border Radius 색상
Base --radius-md (8px) --gray-200 (shimmer: --gray-100)
Title 27px modifier 참고 --radius-md (8px)
Text 24px modifier 참고 --radius-md (8px)
Avatar 60px 60px 50% (원형)
Image 180px 100% --radius-md (8px)
Animation skeleton-shimmer 1.5s ease-in-out infinite — 좌우 반복 shimmer

Code

Base — 단일 라인

<!-- Title 라인 (100% 너비) -->
<div class="skeleton skeleton--title skeleton--w-full"></div>

<!-- Title 라인 (80% 너비) -->
<div class="skeleton skeleton--title skeleton--w-80"></div>

<!-- Text 라인 (60% 너비) -->
<div class="skeleton skeleton--text skeleton--w-60"></div>

<!-- Text 라인 (40% 너비) -->
<div class="skeleton skeleton--text skeleton--w-40"></div>

<!-- Avatar (60×60px 원형) -->
<div class="skeleton skeleton--avatar"></div>

<!-- Image 영역 (100%×180px) -->
<div class="skeleton skeleton--image"></div>

Card Pattern

<div class="skeleton-card">
  <div class="skeleton skeleton--image"></div>
  <div class="skeleton-card__body">
    <span class="skeleton skeleton--title skeleton--w-80"></span>
    <span class="skeleton skeleton--text skeleton--w-60"></span>
    <span class="skeleton skeleton--text skeleton--w-40"></span>
  </div>
</div>

Profile Pattern

<div class="skeleton-profile">
  <div class="skeleton skeleton--avatar"></div>
  <div class="skeleton-profile__body">
    <span class="skeleton skeleton--title skeleton--w-full"></span>
    <span class="skeleton skeleton--text skeleton--w-60"></span>
  </div>
</div>

Paragraph Pattern

<div class="skeleton-paragraph">
  <span class="skeleton skeleton--title skeleton--w-full"></span>
  <span class="skeleton skeleton--text skeleton--w-80"></span>
  <span class="skeleton skeleton--text skeleton--w-60"></span>
</div>

JavaScript — 로딩 후 콘텐츠 전환

const skeleton = document.getElementById('sk-skeleton');
const content  = document.getElementById('sk-content');
const btn      = document.getElementById('sk-btn');
let loaded = false;

btn.addEventListener('click', () => {
  if (loaded) {
    // 초기화: 스켈레톤으로 복귀
    content.style.opacity = '0';
    content.style.pointerEvents = 'none';
    content.setAttribute('aria-hidden', 'true');
    skeleton.style.opacity = '1';
    btn.textContent = '로드 시작';
    loaded = false;
    return;
  }
  // 로딩 시작 (실제 프로젝트에서는 fetch() 등 비동기 작업)
  btn.textContent = '로딩 중...';
  btn.disabled = true;
  setTimeout(() => {
    skeleton.style.opacity = '0';
    content.style.opacity = '1';
    content.style.pointerEvents = '';
    content.setAttribute('aria-hidden', 'false');
    btn.textContent = '다시 보기';
    btn.disabled = false;
    loaded = true;
  }, 1500);
});

Classes

클래스 태그 설명
.skeleton 루트 기본 스켈레톤 블록 — shimmer 애니메이션 적용
.skeleton--title 수정자 타이틀 높이 27px
.skeleton--text 수정자 본문 텍스트 높이 24px
.skeleton--avatar 수정자 원형 아바타 60×60px
.skeleton--image 수정자 이미지 영역 100%×180px
.skeleton--w-full 수정자 너비 100%
.skeleton--w-80 수정자 너비 80%
.skeleton--w-60 수정자 너비 60%
.skeleton--w-40 수정자 너비 40%
.skeleton-card 루트 카드 패턴 래퍼 — 이미지 + 텍스트 세로 배치
.skeleton-card__body 요소 카드 텍스트 영역 (흰 배경, gap 8px)
.skeleton-profile 루트 프로필 패턴 래퍼 — 아바타 + 텍스트 가로 배치
.skeleton-profile__body 요소 프로필 텍스트 영역
.skeleton-paragraph 루트 단락 패턴 래퍼 — 타이틀 + 텍스트 세로 배치