본문으로 건너뛰기
Dot Design System
v0.3.1

Skeleton

예정된 콘텐츠 구조를 유지하며 짧은 로딩을 설명합니다.

목적

Skeleton은 콘텐츠 구조는 알지만 실제 데이터가 아직 준비되지 않은 짧은 대기 상태를 표현한다. 최종 화면의 밀도와 배치를 미리 보여줘 layout 변화를 줄이되, 완료된 정보처럼 오해되지 않게 한다.

선택 기준

  • 초기 목록, 카드, 요약 값처럼 곧 같은 자리에서 실제 콘텐츠로 교체될 때 사용한다.
  • 무엇을 처리하는지 설명해야 하는 긴 작업에는 진행 문구나 DotMotion의 승인된 processing 구성을 검토한다.
  • 즉시 끝나는 작은 action에는 Button의 진행 상태가 더 적절하다.
  • 콘텐츠 구조를 알 수 없는 상태에서 임의의 회색 블록을 많이 만들지 않는다.

실제 패키지 렌더링

기본 사용 예시

예시 데이터

구조

Skeleton은 하나의 div다. 실제로 들어올 제목, 본문, avatar, row의 크기에 맞춰 여러 Skeleton을 composition한다. loading 영역의 parent가 aria-busy와 상태 문구를 소유한다.

변형과 크기

별도 variant나 size prop은 없다. 기본은 둥근 모서리, primary semantic 색의 낮은 투명도, pulse animation을 사용한다. 너비와 높이는 className으로 실제 콘텐츠와 맞춘다.

상태와 동작

Skeleton 자체는 loading 상태를 관리하지 않고 animation만 표시한다. DotTheme의 motion 감소 설정에서는 animation duration과 반복이 최소화된다. 데이터가 준비되면 같은 frame 안에서 실제 콘텐츠로 교체한다. 오류가 발생하면 Skeleton을 계속 보여주지 말고 오류와 복구 action으로 바꾼다.

콘텐츠

Skeleton 안에 실제 text를 넣지 않는다. 별도의 screen-reader 상태 문구는 불러오는 중처럼 현재 작업을 짧게 설명한다. 콘텐츠 종류를 알 수 있으면 최종 형태와 수량을 과장 없이 반영한다.

접근성

장식 placeholder 자체는 의미 있는 콘텐츠로 읽히지 않게 구성하고 parent에 aria-busy="true"를 제공한다. loading 안내가 필요한 경우 화면에 보이는 문구나 live region을 별도로 둔다. pulse animation만으로 loading을 전달하지 않는다.

좁은 화면과 긴 콘텐츠

responsive layout에서 실제 콘텐츠가 한 열로 바뀌면 Skeleton도 같은 구조로 바뀌어야 한다. desktop column 수를 mobile에서 그대로 축소하지 않는다. 긴 목록 전체를 채우기보다 첫 viewport의 예상 행 수만 보여준다.

공개 API

  • Skeleton: React.HTMLAttributes<HTMLDivElement>className을 전달하는 placeholder

전용 variant, size, count, loading prop은 없다.

예제

사용 코드 · TSX
import { Skeleton } from '@classum/dot-design-system/ui';

export function CurriculumRowSkeleton() {
  return (
    <div aria-busy="true" className="flex items-center gap-3 py-3">
      <span className="sr-only" role="status">
        커리큘럼을 불러오는 중
      </span>
      <Skeleton className="size-10 rounded-full" />
      <div className="flex-1 space-y-2">
        <Skeleton className="h-4 w-2/5" />
        <Skeleton className="h-3 w-3/5" />
      </div>
    </div>
  );
}

피해야 할 사용

  • 오류나 빈 상태에서도 Skeleton을 무한히 유지하지 않는다.
  • 실제 layout과 무관한 블록을 장식처럼 반복하지 않는다.
  • loading 의미를 pulse 색 변화만으로 전달하지 않는다.
  • 모든 페이지 요소를 Skeleton으로 채워 우선순위를 없애지 않는다.
  • 일반 네트워크 loading에 캐릭터나 브랜드 gradient를 대신 사용하지 않는다.

관련 항목