04 · Patterns · 피드백 · 상태
로딩 상태Loading
데이터를 기다리는 짧은 순간을 어떻게 시각화할지. 모든 로딩에 스피너를 돌리지 마세요 — 콘텐츠의 형태가 예측되면 스켈레톤이 거의 항상 낫습니다.
세 가지 선택지
스켈레톤
콘텐츠 형태를 미리 보여줌.
스피너
행동의 결과를 기다릴 때.
로딩 중
인라인
버튼·링크 내부에서.
스켈레톤이 맞는 경우
- 콘텐츠 구조가 미리 예상되는 경우(카드 목록, 상세 페이지).
- 로딩이 0.3초 이상 걸릴 것으로 보일 때. 그보다 짧다면 아무것도 보이지 않는 편이 낫습니다.
- 첫 방문, 페이지 전환처럼 사용자가 “새 화면을 기대하는” 순간.
Do· 실제 구조와 닮은 스켈레톤
카드 썸네일 자리, 제목 한 줄, 본문 두 줄 — 실제 레이아웃과 가까울수록 “기대한 것이 올 것”이라는 신뢰가 생깁니다.
Don't· 회색 블럭 전체
화면 전체를 거대한 회색 사각형 하나로 채우면 스켈레톤이 아니라 그냥 로딩 중 화면입니다. 구조가 없다면 스피너가 더 낫습니다.
스피너가 맞는 경우
- 사용자의 행동 직후(버튼 클릭 → 응답). 화면 구조는 이미 있고 그 안의 결과만 바뀜.
- 결과 형태를 예측할 수 없는 작업(파일 처리, AI 응답).
- 구조적으로 스켈레톤을 만들기 어려운 소형 영역.
인라인 로딩
버튼이나 링크 내부에서 ‘지금 이 행동이 진행 중’을 알리는 로딩. 버튼은 비활성화 + 스피너 + 텍스트 전환(“저장” → “저장 중…”)이 완성형입니다.
텍스트만 바꾸거나 스피너만 넣는 반쪽은 상태가 애매해집니다. 셋 다 바꿔야 “눌렀다”는 확신을 줍니다.
오래 걸리는 작업
- 5초 이상 예상되면 진행률(Progress) 바와 단계 안내.
- 30초 이상은 작업을 백그라운드로 전환하고 “완료되면 알려드릴게요”가 정답.
- 실패 가능성이 있으면 ‘취소’ 버튼. 사용자가 포기할 선택지도 주세요.
접근성
- 스피너는
role="status"+ 숨긴 라벨(“불러오는 중”). - 스켈레톤은
aria-hidden="true"로 기계가 무시하게. 대신 상위 영역에aria-busy="true"를 부여. - 로딩 완료 후 콘텐츠가 들어온다는 사실을
aria-live="polite"로 알림.