Explorer
KNOW-PAT-117

Web UI/UX - Skeleton Loading State avec Stagger Delay : grid cards, shimmer animation, CSS pur

Domaine
web-uiux
Type
pattern
Priorité
P2

Parent : [[INDEX-WEB-UIUX]]

Web UI/UX - Skeleton Loading State avec Stagger Delay : grid cards, shimmer animation, CSS pur

Problème

Un spinner centré pendant 2 secondes donne l'impression que l'appli est cassée. Les skeletons correctement animés donnent une sensation de vitesse et montrent la structure avant que les données arrivent.

Solution

Skeleton CSS avec animation shimmer (gradient qui se déplace), stagger delay pour les cards successives, et grid de skeleton cards qui mimique la vraie layout.

/* globals.css */
.skeleton {
  background: linear-gradient(90deg, var(--surface) 25%, var(--surface-2) 50%, var(--surface) 75%);
  background-size: 400% 100%;
  animation: skeleton-sweep 1.4s ease infinite;
}

@keyframes skeleton-sweep {
  0% { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}
// Grid de skeleton cards pendant le chargement
{loading && (
  <div className="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 gap-4">
    {Array.from({ length: 8 }).map((_, i) => (
      <div
        key={i}
        className="rounded-[6px] overflow-hidden"
        style={{ border: '1px solid var(--border)', animationDelay: `${i * 60}ms` }}
      >
        <div className="skeleton h-48 w-full" />
        <div className="p-4 flex flex-col gap-2.5" style={{ background: 'var(--surface)' }}>
          <div className="skeleton h-3 w-1/4 rounded" />  {/* Tag */}
          <div className="skeleton h-4 w-full rounded" />   {/* Title */}
          <div className="skeleton h-3 w-3/4 rounded" />  {/* Desc */}
          <div className="skeleton h-3 w-1/2 rounded" />   {/* Footer */}
        </div>
      </div>
    ))}
  </div>
)}

Points clés

  1. animationDelay: ${i * 60}ms : stagger de 60ms entre chaque card → effet "vague"
  2. Mimic la vraie structure : image h-48 + 4 lignes de texte = même forme que les vraies cards
  3. background-size: 400% 100% : le gradient doit être 4x plus large que l'élément pour pouvoir se déplacer
  4. var(--surface)var(--surface-2)var(--surface) : utilise les tokens du design system
  5. 8 skeletons : nombre suffisant pour remplir l'écran sans en créer 50

Pourquoi

  • Les skeletons réduisent la perception du temps de chargement de 30-40%
  • Le stagger crée une sensation de fluidité
  • Le shimmer indique "ça charge activement" vs "c'est figé"

Quand l'utiliser

  • Grids, listes, dashboards avec chargement de données
  • Page transitions avec fetch

Quand NE PAS l'utiliser

  • Chargement < 200ms (le vrai contenu arrive trop vite)
  • Actions instantanées (toggle switch) → pas besoin

Références

  • ProjectAlpha/globals.css L115-124
  • ProjectAlpha/GlobalSearch.tsx L360-374