Skeleton Loading

Loading state indicators that show content structure while data is being fetched. Skeleton components provide visual feedback during loading states, improving perceived performance.

Best Practices

When to Use

  • Approach 1 (Single Block): Use for lists with many cards or simple/unpredictable content
  • Approach 2 (Detailed Elements): Use for hero cards, dashboards, or when the card is a primary focus
  • Approach 3 (Hybrid): Use when you want layout hints without per-element animation overhead

Design Guidelines

  • Color: Uses --grey-600 at low opacity for subtle appearance
  • Animation: Subtle shimmer from left to right at 1.5s interval
  • Sizing: Match skeleton dimensions to loaded content
  • Layout: Maintain same spacing as loaded state

Approach 1: Single Block

Best for performance and simplicity. A single skeleton replaces the entire card. Ideal for list views with many items or when the content structure is unpredictable.

Skeleton
Loaded
JD

John Doe

Software Engineer

A brief description about this user.

Usage
<div className="skeleton-card" style={{ width: 280, height: 180 }} />

Approach 2: Detailed Elements

Best for UX when the layout is fixed and known. Each element gets its own skeleton. Provides visual hints about the content structure while loading.

Skeleton
Loaded
JD

John Doe

Software Engineer

A brief description about this user.

Usage
<div className="card">
  <div className="card-header">
    <div className="skeleton skeleton-avatar skeleton-stagger-1" />
    <div>
      <div className="skeleton skeleton-title skeleton-stagger-2" />
      <div className="skeleton skeleton-subtitle skeleton-stagger-3" />
    </div>
  </div>
  <div className="card-body">
    <div className="skeleton skeleton-text skeleton-stagger-4" />
    <div className="skeleton skeleton-text skeleton-text-short skeleton-stagger-5" />
  </div>
  <div className="card-actions">
    <div className="skeleton skeleton-btn skeleton-stagger-4" />
    <div className="skeleton skeleton-btn skeleton-stagger-5" />
  </div>
</div>

Approach 3: Hybrid

Middle ground - shows card structure with a single shimmer across the whole card. Individual elements do not animate separately, reducing animation overhead.

Skeleton
Loaded
JD

John Doe

Software Engineer

A brief description about this user.

Usage
<div className="skeleton-card-hybrid">
  {/* Elements without individual shimmer */}
  <div className="skeleton skeleton-avatar" />
  <div className="skeleton skeleton-title" />
  <div className="skeleton skeleton-text" />
  {/* Single shimmer animates across entire card */}
</div>

Button Skeleton

Use when buttons are loading or disabled during async actions.

Usage
<div className="skeleton skeleton-btn" style={{ width: 120 }} />

Available Classes

/* Base skeleton - adds shimmer animation to any element */
.skeleton

/* Card-level skeletons */
.skeleton-card           /* Simple single-block card replacement */
.skeleton-card-hybrid    /* Card with single shimmer over all elements */

/* Element skeletons - combine with .skeleton */
.skeleton-avatar         /* 48x48px circle */
.skeleton-title          /* 16px height, 70% width */
.skeleton-subtitle       /* 12px height, 50% width */
.skeleton-text           /* 12px height, 100% width */
.skeleton-text-short     /* Modifier: reduces width to 80% */
.skeleton-btn            /* 40px height button placeholder */

/* Staggered animation delays */
.skeleton-stagger-1      /* 0s delay */
.skeleton-stagger-2      /* 0.1s delay */
.skeleton-stagger-3      /* 0.2s delay */
.skeleton-stagger-4      /* 0.3s delay */
.skeleton-stagger-5      /* 0.4s delay */