Navigation✨ Premium

Skeleton Card

Placeholder de carte animé en CSS pur : un dégradé linéaire à faible opacité défile en boucle pour simuler le scintillement de chargement — zéro JavaScript, zéro dépendance.

CSSLoadingShimmer

Vous aurez accès à la démo interactive avec un compte gratuit.

Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Navigation comprend 36 effets, dont 4 gratuits. Découvrir la catégorie →

3 exemples d'usage

Dashboard SaaS — Grille de cartes produit en cours de chargement — Skeleton Card exemple 1

① Dashboard SaaS — Grille de cartes produit en cours de chargement

QuandL'utilisateur navigue vers une section du tableau de bord dont les données sont récupérées via API — cartes KPI, produits, articles.
PourquoiLe squelette reproduit exactement la forme des futures cartes (image + titre + lignes), ce qui prévient le saut de mise en page et ancre l'attention pendant la requête.
Réglagesmax-width 280px, animation-duration 1,5 s. Instanciez plusieurs .skeleton-card côte à côte dans une grille CSS pour simuler une liste réaliste de 3 à 6 cartes.
Fil d'articles — Blog ou actualités avec chargement paresseux — Skeleton Card exemple 2

② Fil d'articles — Blog ou actualités avec chargement paresseux

QuandLe défilement infini charge un nouveau lot d'articles : le squelette s'affiche pendant la requête et laisse place au contenu réel une fois reçu.
PourquoiL'animation continue de scintillement signale clairement que la page est active — les utilisateurs patientent plutôt que de douter d'un bug ou d'un réseau lent.
RéglagesEmpilez 3 à 6 .skeleton-card verticalement (max-width 100%). Réduisez .skeleton-image à 80 px pour les listes compactes avec miniature horizontale.
Galerie vidéo — Médiathèque ou catalogue de cours asynchrones — Skeleton Card exemple 3

③ Galerie vidéo — Médiathèque ou catalogue de cours asynchrones

QuandLes vignettes et métadonnées des vidéos sont chargées depuis un CDN ou une API externe (YouTube, Vimeo, service interne).
PourquoiLe ratio image/texte du squelette correspond naturellement aux miniatures vidéo, rendant la transition chargement→contenu fluide sans saut visuel.
RéglagesAjustez .skeleton-image à 157 px (ratio 16:9 sur 280 px) et réduisez à 2 lignes (supprimez le troisième .skeleton-line) pour les titres courts.

Comment ça marche

Le scintillement repose sur une seule règle @keyframes shimmer qui anime background-position de 200% 0 à -200% 0. Le fond de chaque zone squelette est un linear-gradient(90deg) avec des stops très peu opaques (5 % · 10 % · 5 %) et un background-size: 200% 100% — quand la position défile, la bande lumineuse centrale balaie la surface de gauche à droite sans aucun calcul côté moteur.

Trois zones reproduisent l'anatomie d'une carte de contenu : image (120 px de hauteur, border-radius: 8px), titre (70 % de largeur, 16 px de hauteur) et lignes de texte (100 % · 90 % · 60 % de largeur). Les proportions inégales évitent l'effet de grille uniforme et imitent la typographie réelle d'une carte produit ou d'un article.

Les trois lignes portent des animation-delay échelonnés (0,1 s · 0,2 s · 0,3 s), ce qui crée un décalage de phase visible : la lumière semble progresser de haut en bas plutôt que de clignoter simultanément sur tout le composant.

L'animation tourne à durée fixe de 1,5 s en boucle infinite avec un timing-function: ease. Pas de JavaScript : le composant est entièrement autonome en CSS et s'intègre tel quel dans React, Vue, Angular ou Svelte sans initialisation.

Accessibilité

  • prefers-reduced-motion absent : le code ne contient aucune règle @media (prefers-reduced-motion: reduce). Pour les utilisateurs sensibles aux animations continues, ajoutez dans votre feuille de styles : .skeleton-image, .skeleton-title, .skeleton-line { animation: none; } conditionné au media query.
  • Les éléments squelettes sont des <div> vides — ajoutez aria-hidden="true" sur .skeleton-card et un aria-live="polite" sur le conteneur parent pour que les lecteurs d'écran annoncent le changement d'état une fois le contenu réel injecté.
  • Le squelette ne comporte aucun rôle interactif ni élément focusable : aucun problème de navigation clavier inhérent au composant.
  • Les opacités très basses (5 % / 10 %) sont intentionnelles — le squelette est un placeholder, pas du contenu ; il n'atteint pas les seuils de contraste WCAG, ce qui est attendu.
  • Durée indéfinie : si le contenu ne charge pas, l'animation tourne sans fin — respectez WCAG 2.2.2 en exposant un mécanisme pour masquer ou interrompre le squelette après un délai raisonnable.

Compatibilité navigateur

Repose uniquement sur @keyframes, linear-gradient et background-position animée — disponibles dans tous les navigateurs modernes depuis 2015.

Chrome 49+✓ Complet
Firefox 46+✓ Complet
Safari 10+✓ Complet
Edge 79+✓ Complet
Mobile iOS✓ Complet
Android Chrome✓ Complet

Sans prise en charge des animations CSS, les zones squelettes s'affichent comme des blocs statiques à faible opacité — aucun JavaScript n'est requis, aucune erreur ne survient.

Le code

Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :

index.html — structure
<div class="skeleton-card">
  <div class="skeleton-image"></div>
  <div class="skeleton-content">
    <div class="skeleton-title"></div>
    <div class="skeleton-text">
      <div class="skeleton-line"></div>
      <div class="skeleton-line"></div>
      <div class="skeleton-line"></div>
    </div>
  </div>
</div>
🔒 Débloquer le code complet — à partir de 2,99 € le 1er mois

HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
animation-duration (1,5 s) 1.5s Vitesse du balayage lumineux. Augmentez à 2,5 s pour un rendu plus doux, réduisez à 0,8 s pour un chargement rapide perçu.
.skeleton-card max-width 280px Largeur maximale de la carte. Passez à 100% pour une carte pleine largeur ou adaptez à votre grille.
.skeleton-image height 120px Hauteur du bloc image placeholder. 157 px ≈ ratio 16:9 sur 280 px, 280 px = carré parfait.
gradient opacity stops .05 / .10 / .05 Opacité des stops rgba(255,255,255,…). Montez à .10 / .20 / .10 pour un scintillement plus visible, notamment sur fond clair en inversant vers rgba(0,0,0,…).
.skeleton-title width 70% Largeur de la barre de titre placeholder. Variez entre 40 % et 85 % selon la longueur typique de vos titres réels.
animation-delay par ligne .1s / .2s / .3s Décalage de phase entre les lignes. Augmentez à .2 s / .4 s / .6 s pour une cascade plus marquée ; mettez 0 s partout pour un scintillement synchrone.
border-radius .skeleton-card 12px Arrondi de la carte. 0 px pour un layout de liste pleine largeur, 16–20 px pour un style carte « flottante ».

FAQ

Retirez (ou masquez avec display: none) l'élément .skeleton-card et injectez le HTML de la vraie carte à sa place. Ajoutez une transition de fondu (opacity 0→1 en 200 ms) sur la carte réelle pour une permutation invisible.
Oui — les classes skeleton-* sont partagées. Incluez le CSS une seule fois dans votre page ou bundle, puis instanciez autant de .skeleton-card que nécessaire. En React ou Vue, créez un composant <SkeletonCard /> qui rend uniquement le HTML du squelette sans style supplémentaire.
Le dégradé par défaut est calibré pour un fond sombre (#0a0a0f). Sur fond clair, inversez les stops : remplacez rgba(255,255,255,.05) par rgba(0,0,0,.05) et rgba(255,255,255,.10) par rgba(0,0,0,.12), et ajustez le fond de .skeleton-card à rgba(0,0,0,.04).