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.
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



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 — ajoutezaria-hidden="true"sur.skeleton-cardet unaria-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.
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) :
<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>
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éfaut | Effet |
|---|---|---|
| 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
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.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.#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).