loading-states

dylantarre's avatarfrom dylantarre

Use when indicating progress or waiting - spinners, progress bars, skeleton screens, shimmer effects, or any animation showing the system is working.

⭐0stars🔀0forks📁View on GitHub🕐Updated Dec 30, 2025

When & Why to Use This Skill

The Loading States skill empowers developers and designers to implement professional-grade UI animations and progress indicators. By integrating Disney's 12 animation principles into web development, it provides optimized CSS patterns for skeleton screens, spinners, and progress bars. This skill focuses on enhancing perceived performance and user experience (UX) through precise timing recommendations and smooth transition techniques that prevent UI flickering and layout shifts.

Use Cases

  • Scenario 1: Designing and implementing skeleton screens that match content proportions to provide a seamless transition from loading to active states.
  • Scenario 2: Creating high-performance CSS spinners with built-in delays (e.g., 200ms) to avoid jarring visual flashes during rapid data fetching.
  • Scenario 3: Applying advanced motion principles like 'Slow In/Slow Out' and 'Squash & Stretch' to make system waiting periods feel more organic and less tedious.
  • Scenario 4: Optimizing web accessibility by implementing 'prefers-reduced-motion' checks and ensuring loading indicators follow smooth, non-distracting animation cycles.
  • Scenario 5: Standardizing loading behaviors across a design system using specific timing rules for buttons, full-page transitions, and indeterminate progress bars.
nameloading-states
descriptionUse when indicating progress or waiting - spinners, progress bars, skeleton screens, shimmer effects, or any animation showing the system is working.

Loading State Animations

Apply Disney's 12 principles to communicate system activity.

Principle Application

Squash & Stretch: Progress indicators can pulse/breathe to show life. Slight scale oscillation (0.98-1.02).

Anticipation: Show loading state immediately on action. Don't wait for slow response to show spinner.

Staging: Loading indicators appear where content will be. Skeleton screens match final layout.

Straight Ahead vs Pose-to-Pose: Design loading as a sequence: instant indicator → progress → completion → content.

Follow Through & Overlapping: Loading fades as content enters. Overlap the transition by 100ms.

Slow In/Slow Out: Progress bars ease-in-out between known percentages. Indeterminate uses smooth oscillation.

Arcs: Circular spinners follow true circular paths. Avoid jerky rotation.

Secondary Action: Skeleton shimmer + subtle pulse. Multiple signals reinforce "loading."

Timing:

  • Show spinner after 200ms delay (avoid flash for fast loads)
  • Minimum display: 500ms (prevent jarring flash)
  • Skeleton shimmer cycle: 1500-2000ms

Exaggeration: Keep minimal - loading shouldn't distract, just reassure.

Solid Drawing: Skeletons should match content proportions. Wrong shapes break the illusion.

Appeal: Loading should feel optimistic, not tedious. Smooth motion suggests progress.

Timing Recommendations

Loading Type Appear Delay Min Display Animation Cycle
Spinner 200ms 500ms 700-800ms
Progress Bar 0ms - smooth fill
Skeleton 0ms 500ms 1500ms shimmer
Button Spinner 0ms 400ms 600ms
Full Page 100ms 800ms 1000ms

Implementation Patterns

/* Skeleton shimmer */
.skeleton {
  background: linear-gradient(
    90deg,
    #e0e0e0 0%,
    #f0f0f0 50%,
    #e0e0e0 100%
  );
  background-size: 200% 100%;
  animation: shimmer 1500ms ease-in-out infinite;
}

@keyframes shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Spinner with smooth rotation */
.spinner {
  animation: spin 700ms linear infinite;
  opacity: 0;
  animation: fade-in 200ms 200ms ease-out forwards, spin 700ms linear infinite;
}

/* Progress bar with easing */
.progress-fill {
  transition: width 300ms cubic-bezier(0.4, 0, 0.2, 1);
}

Loading-to-Content Transition

.content-enter {
  animation: content-reveal 300ms ease-out forwards;
}

@keyframes content-reveal {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

Key Rules

  1. Delay spinner appearance by 200ms to avoid flash
  2. Keep loading visible minimum 500ms once shown
  3. Skeleton shapes must match real content dimensions
  4. Transition smoothly from loading to content - never pop
  5. Respect prefers-reduced-motion - show static indicator instead