Loading States
Create smooth, engaging loading experiences with our skeleton components. Each component follows consistent patterns, uses glass morphism effects, and includes built-in accessibility features for modern loading placeholders.
Available Components
Core Components
- Skeleton - Basic skeleton shapes and variants for all content types
- SkeletonText - Multi-line text blocks with natural line width variation
- SkeletonCard - Pre-composed card skeletons for structured content
Layout Components
- SkeletonImage - Image and media placeholders with aspect ratio support
- SkeletonList - List and grid layouts with repeating skeleton items
Design Principles
1. Glass Morphism Effects
All skeleton components use subtle glass morphism with backdrop blur for a sophisticated, modern appearance that integrates seamlessly with the design system:
/* Skeleton base styling */
background: color-mix(in oklch, var(--surface) 92%, var(--neutral-500));
backdrop-filter: blur(8px);
border: 1px solid color-mix(in oklch, var(--surface) 85%, var(--neutral-400)); 2. Animation Consistency
Three animation types available across all skeleton components:
- Shimmer - Wave-like effect for active loading states
- Pulse - Gentle opacity animation for subtle loading
- None - Static for mockups or reduced motion preferences
3. Accessibility First
Every skeleton component includes:
role="status"andaria-live="polite"for screen reader announcements- Hidden “Loading…” text for assistive technology
- Respects
prefers-reduced-motionmedia query - Proper semantic structure maintained
Loading Patterns
Progressive Loading
Show skeletons for slow content while displaying fast content immediately:
<script>
import Skeleton from '$lib/shared/components/loading/Skeleton.svelte';
import SkeletonText from '$lib/shared/components/loading/SkeletonText.svelte';
let userLoaded = $state(false);
let contentLoaded = $state(false);
// Fast-loading user data
onMount(async () => {
const user = await fetchUser(); // Fast: 100ms
userLoaded = true;
});
// Slow-loading content
onMount(async () => {
const content = await fetchContent(); // Slow: 2s
contentLoaded = true;
});
</script>
<article class="post">
<div class="author">
{#if userLoaded}
<img src={user.avatar} alt={user.name} />
<span>{user.name}</span>
{:else}
<Skeleton variant="avatar" size="sm" />
<Skeleton variant="text" width="120px" />
{/if}
</div>
<div class="content">
{#if contentLoaded}
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
{:else}
<Skeleton variant="heading" />
<SkeletonText lines={3} />
{/if}
</div>
</article> Structured Loading
Match skeleton structure to actual content layout:
<!-- Article card skeleton -->
<div class="article-card">
<Skeleton variant="image" />
<div class="content">
<Skeleton variant="heading" />
<SkeletonText lines={2} lastLineWidth="60%" />
<div class="meta">
<Skeleton variant="avatar" size="sm" />
<div>
<Skeleton variant="text" width="100px" />
<Skeleton variant="text" width="80px" />
</div>
</div>
</div>
</div> List Loading
Use repeating patterns for consistent list experiences:
<!-- Product list skeleton -->
<div class="product-grid">
{#each Array(6) as _, i}
<div class="product-card">
<Skeleton variant="image" />
<Skeleton variant="title" />
<SkeletonText lines={2} />
<Skeleton variant="button" />
</div>
{/each}
</div> Animation Guidelines
Performance Optimization
Skeleton animations are optimized for performance:
- Uses
transformandopacityfor GPU acceleration - Respects
prefers-reduced-motionautomatically - Consistent 1.5s duration across all animations
- Minimal impact on layout reflow
Animation Selection
Choose animations based on context:
<!-- Active loading - use shimmer -->
<Skeleton variant="text" animation="shimmer" />
<!-- Subtle/background loading - use pulse -->
<Skeleton variant="text" animation="pulse" />
<!-- Static mockups - no animation -->
<Skeleton variant="text" animation="none" /> Layout Integration
Spacing Consistency
Use design system spacing tokens for skeleton layouts:
.skeleton-layout {
display: flex;
flex-direction: column;
gap: var(--space-4);
padding: var(--space-6);
}
.skeleton-meta {
display: flex;
align-items: center;
gap: var(--space-3);
} Responsive Behavior
Skeletons adapt to their containers naturally:
<!-- Responsive grid -->
<div class="responsive-grid">
{#each Array(8) as _, i}
<SkeletonCard />
{/each}
</div>
<style>
.responsive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: var(--space-4);
}
</style> Dark Mode Support
All skeleton components automatically adjust for dark mode:
/* Automatic dark mode adjustments */
:global(.dark) .skeleton-base {
background: color-mix(in oklch, var(--surface) 96%, var(--neutral-600));
border-color: color-mix(in oklch, var(--surface) 90%, var(--neutral-500));
} Best Practices
1. Match Content Structure
Ensure skeleton dimensions match actual content:
- Use same aspect ratios for images
- Match text line heights and spacing
- Replicate card layouts exactly
- Mirror navigation structures
2. Timing Considerations
Optimize loading timing:
- Show skeletons immediately (no delay)
- Maintain for minimum 300ms (avoid flashing)
- Fade transition between skeleton and content
- Handle race conditions gracefully
3. Progressive Disclosure
Load content intelligently:
- Prioritize above-the-fold content
- Show critical information first
- Use skeleton for secondary content
- Implement infinite scroll with skeletons
4. Error States
Handle loading failures:
- Replace skeleton with error message
- Provide retry mechanisms
- Use different styling for error states
- Maintain accessibility during errors
Performance Tips
- Reuse Components - Create skeleton variants for common layouts
- Minimize Animations - Use static skeletons for long lists
- Smart Loading - Only show skeletons for slow operations
- Cache Strategies - Combine skeletons with data caching
- Batch Updates - Group skeleton-to-content transitions
Accessibility Checklist
Screen Reader Support
- ✓ Skeleton announces “Loading…” status
- ✓ Content replacement announced automatically
- ✓ Loading progress communicated clearly
- ✓ Error states properly announced
Visual Indicators
- ✓ Sufficient contrast in light and dark modes
- ✓ Motion respects user preferences
- ✓ Clear loading state differentiation
- ✓ Consistent timing across components
Keyboard Navigation
- ✓ Focus management during loading
- ✓ Skip links work during skeleton states
- ✓ Tab order maintained through transitions
- ✓ Interactive elements properly disabled
Related Resources
- Typography System - Text styling consistency
- Color System - Surface and neutral tokens
- Spacing System - Layout spacing patterns
- Loading States - Other loading patterns