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
animationDelay: ${i * 60}ms: stagger de 60ms entre chaque card → effet "vague"- Mimic la vraie structure : image h-48 + 4 lignes de texte = même forme que les vraies cards
background-size: 400% 100%: le gradient doit être 4x plus large que l'élément pour pouvoir se déplacervar(--surface)→var(--surface-2)→var(--surface): utilise les tokens du design system- 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