List Skeleton
Quatre rangées [avatar 40 px + 2 lignes] en CSS pur : shimmer à 1,8 s synchronisé sur 12 os, largeurs de ligne variables d'une rangée à l'autre.
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. Chargement comprend 29 effets, dont 4 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Le code crée quatre blocs .list-skel-item dans un conteneur .list-skel large de 280 px, en colonne (flex-direction: column, gap: 4px). Chaque item est un flex horizontal avec padding: 12px 16px, fond rgba(255,255,255,.02) et coins à 12 px. Il contient un cercle .skel-bone-circle .list-skel-avatar (40×40 px, flex-shrink: 0) et un bloc de texte .list-skel-text (flex: 1) avec deux os : .list-skel-line1 (hauteur 12 px, marge basse 8 px) et .list-skel-line2 (hauteur 9 px). Les classes .skel-bone et .skel-bone-circle donnent à chaque os le fond rgba(255,255,255,.08) et la position relative nécessaire au pseudo-élément du shimmer. Le HTML compte en tout 12 os animés (4 cercles + 4 lignes principales + 4 sous-lignes).
Les largeurs de ligne varient d'un item à l'autre via des attributs style inline sur les blocs concernés : list-skel-line1 à 70 % (défaut CSS), 60 %, 80 %, 50 % ; list-skel-line2 à 50 % (défaut CSS), 40 %, 55 %, 35 %. Ces variations sont statiques et codées en dur dans le HTML — aucun JavaScript ne les génère. Le premier item n'a pas de style : ses largeurs sont fixées par les règles CSS (.list-skel-line1 à 70 %, .list-skel-line2 à 50 %).
Le shimmer est produit par le pseudo-élément ::after de chaque os, en position: absolute; inset: 0, avec le fond linear-gradient(90deg, transparent 0, rgba(255,255,255,.1) 50%, transparent 100%) sur un background-size: 200% 100%. L'animation shimmerSlide déplace ce fond de background-position: -200% à 200% en 1,8 s ease-in-out, délai 0 s, infini. Tous les 12 os partagent le même délai : le shimmer est synchronisé, non décalé. Zéro JavaScript — l'effet entier est CSS pur.
Accessibilité
- prefers-reduced-motion absent du code : mesuré sous
reducedMotion: 'reduce'(Playwright/Chromium), les 12 animations continuent de tourner (animationPlayState: running,animationDuration: 1.8s). Ajoutez@media (prefers-reduced-motion: reduce) { .skel-bone::after, .skel-bone-circle::after { animation: none } }. - Le skeleton est un indicateur de chargement et non un contenu : posez
role="status"ouaria-busy="true"sur le conteneur parent de la liste réelle (pas sur.list-skellui-même), et retirez.list-skeldu DOM une fois le contenu arrivé. Aucun texte alternatif à fournir sur les os. - Posez
aria-hidden="true"sur.list-skel: les 12 os vides ne doivent pas être traversés par les lecteurs d'écran. Annoncez la fin du chargement via une zonearia-live="polite"existante dans votre interface. - Le fond des os (
rgba(255,255,255,.08)) et le flash du shimmer (rgba(255,255,255,.1)) n'ont de sens que sur un fond sombre. Sur un fond clair, os et shimmer deviennent invisibles : remplacez parrgba(0,0,0,.06)etrgba(0,0,0,.08).
Compatibilité navigateur
CSS pur, sans JavaScript. Requiert @keyframes, animation, inset (raccourci Chrome 87+, Firefox 87+, Safari 14.1+), border-radius: 50%, display: flex et overflow: hidden. Aucune dépendance.
Sans CSS ou sur un navigateur antérieur à Safari 14.1 (propriété inset absente), les pseudo-éléments ::after ne se positionnent pas et le shimmer est invisible — les os restent de simples rectangles et cercles sombres sans animation, ce qui constitue un repli acceptable pour un état de chargement.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="list-skel">
<div class="list-skel-item">
<div class="skel-bone-circle list-skel-avatar"></div>
<div class="list-skel-text">
<div class="skel-bone list-skel-line1"></div>
<div class="skel-bone list-skel-line2"></div>
</div>
</div>
<!-- … 3 autres items, ex. list-skel-line1 style="width:60%" et list-skel-line2 style="width:40%" -->
</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 |
|---|---|---|
Nombre d'items (HTML — blocs .list-skel-item) |
4 | Dupliquez ou retirez des blocs. Chaque item ajoute ~65 px de hauteur (40 px d'avatar + paddings + gap). Pour des largeurs de lignes réalistes, variez les attributs style="width:…" d'un item à l'autre. |
Taille de l'avatar (CSS — .list-skel-avatar { width; height }) |
40×40 px | L'avatar est centré verticalement dans l'item par align-items: center. À 48 px il représente une photo de profil ; à 32 px une icône compacte. Changez les deux propriétés ensemble. |
Hauteur de la ligne principale (CSS — .list-skel-line1 { height }) |
12 px | Cible le titre ou le nom dans la rangée. 14px pour aligner avec un texte de base à font-size: 14px ; 10px pour une liste dense. |
Hauteur de la sous-ligne (CSS — .list-skel-line2 { height }) |
9 px | Cible le sous-titre, l'horodatage ou le résumé. Maintenir un rapport ≥ 0,7 avec la ligne principale préserve la lisibilité de la hiérarchie au moment où le vrai contenu arrive. |
Largeurs de lignes (HTML — attributs style="width:…" sur chaque os) |
Line1 : 70 / 60 / 80 / 50 % — Line2 : 50 / 40 / 55 / 35 % | Les largeurs CSS par défaut (70 % / 50 %) s'appliquent quand l'attribut est absent. Variez les valeurs pour simuler des contenus de longueurs différentes ; des valeurs trop proches rendent la liste uniforme et moins crédible. |
Espacement entre items (CSS — .list-skel { gap }) |
4 px | 0 = liste unie sans séparation visible (style type flux) ; 8px = entrées distinctes, similaire à un espaceur de 8 px entre cartes. Au-delà de 12 px, l'aspect liste se perd. |
Durée du shimmer (CSS — animation: 1.8s ease-in-out 0s infinite) |
1,8 s | Modifiez la durée dans la déclaration animation du sélecteur .skel-bone-circle::after, .skel-bone::after. 1,2s donne un sentiment d'urgence ; 2,5s suggère un chargement long ou paresseux. |
FAQ
animation: 1.8s ease-in-out 0s infinite, délai 0 s. Pour un effet de vague descendante, ajoutez un délai croissant sur chaque item : .list-skel-item:nth-child(2) .skel-bone::after, .list-skel-item:nth-child(2) .skel-bone-circle::after { animation-delay: .15s }, et ainsi de suite avec 0,15 s d'incrément par rang.rgba(255,255,255,.08) et le flash du shimmer rgba(255,255,255,.1) — deux blancs translucides, invisibles sur un fond blanc ou gris clair. Sur un fond clair, remplacez ces valeurs par rgba(0,0,0,.06) et rgba(0,0,0,.08) dans les sélecteurs .skel-bone, .skel-bone-circle et .skel-bone-circle::after, .skel-bone::after.