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-600at 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
John Doe
Software Engineer
A brief description about this user.
<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
John Doe
Software Engineer
A brief description about this user.
<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
John Doe
Software Engineer
A brief description about this user.
<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.
<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 */