Chargement✨ Premium

Profile Skeleton

Dix os CSS en colonne : cercle de 80 px, nom (130×16 px), deux lignes de bio et trois blocs statistiques — shimmer synchrone de 1,8 s, zéro JavaScript.

CSSShimmerProfil

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

Application mobile de réseau social — profil utilisateur en cours de chargement — Profile Skeleton exemple 1

① Application mobile de réseau social — profil utilisateur en cours de chargement

QuandÉcran de profil d'une application : l'utilisateur a tapé sur un avatar dans son fil ; la page s'ouvre et les données réseau arrivent en 300 à 800 ms.
PourquoiLa forme du squelette — grand cercle, nom, bio courte, statistiques — correspond exactement à l'anatomie d'un profil Instagram, Twitter ou LinkedIn : l'utilisateur reconnaît immédiatement la structure à venir. Un spinner anonyme n'offre pas cet ancrage.
RéglagesAvatar à 96 px (width/height: 96px), nom à width: 150px; height: 18px, fond des os à rgba(255,255,255,.1) pour un contraste plus franc sur un fond sombre #111.
Forum ou communauté — fiche de l'auteur d'un message — Profile Skeleton exemple 2

② Forum ou communauté — fiche de l'auteur d'un message

QuandDans un fil de discussion, chaque message affiche en colonne latérale la fiche de son auteur (avatar, pseudo, statistiques de participation). La fiche est chargée à la demande quand le fil devient visible.
PourquoiLe squelette est compact (260 px de large) et vertical, adapté à une colonne de type aside. Les trois blocs statistiques simulent des métriques de participation — sujets, réponses, réactions — qui figurent parmi les premières données demandées.
RéglagesAvatar réduit à 56 px, nom à width: 100px; height: 14px, les deux lignes de bio supprimées (absentes d'une fiche d'auteur courte), blocs statistiques conservés.
Tableau de bord RH — fiche collaborateur en chargement différé — Profile Skeleton exemple 3

③ Tableau de bord RH — fiche collaborateur en chargement différé

QuandUne grille de fiches collaborateurs se charge en lazy-load : les fiches hors écran reçoivent d'abord le squelette, puis les données réelles quand elles entrent dans le viewport.
PourquoiL'aspect profil (cercle centré + métriques chiffrées) est naturel pour une fiche RH ou un annuaire d'entreprise. Les trois blocs statistiques peuvent représenter des KPI — projets, absences, ancienneté. Aucun JavaScript supplémentaire : un IntersectionObserver retire le squelette quand les données arrivent.
RéglagesFond des os à rgba(255,255,255,.06) sur une grille en thème clair (fond #f8f8f8), shimmer à rgba(0,0,0,.08).

Comment ça marche

Le HTML expose une seule colonne : .profile-skel (260 px, flex colonne, éléments centrés, gap : 12 px) contient quatre os dans la colonne principale, puis .profile-skel-stats (flex ligne, gap : 20 px, margin-top : 8 px) répartit trois blocs côte à côte. Deux classes portent les os : .skel-bone pour les rectangles (border-radius : 6 px) et .skel-bone-circle pour l'avatar (border-radius : 50 %). Dimensions mesurées : avatar 80×80 px, nom 130×16 px, bio1 200×10 px, bio2 160×10 px — les deux largeurs différentes évoquent du texte naturel. Chaque bloc stat regroupe un nombre (36×18 px, border-radius : 4 px) et une étiquette (48×9 px, border-radius : 4 px). Fond de base : rgba(255,255,255,.08). Zéro JavaScript.

Le shimmer est entièrement dans les pseudo-éléments : .skel-bone::after et .skel-bone-circle::after recouvrent chaque os (position : absolute ; inset : 0) et portent un dégradé linear-gradient(90deg, transparent 0, rgba(255,255,255,.1) 50%, transparent 100%) déclaré sur 200 % de la largeur de l'élément. L'animation shimmerSlide déplace background-position de -200% 0 à 200% 0 : une bande lumineuse centrée traverse l'os de gauche à droite, disparaît, et recommence. Durée : 1,8 s, courbe ease-in-out, délai 0 s, boucle infinie.

Tous les dix os partagent le même délai de 0 s : le shimmer les traverse simultanément. Sur la colonne de 260 px, la bande lumineuse balaye le profil entier d'un coup, sans décalage de haut en bas. Le pic du shimmer est rgba(255,255,255,.10) sur un fond de base rgba(255,255,255,.08) — un écart de deux points d'opacité, discret sur fond très sombre (#0a0a0f). Sur un fond plus clair ou une page en thème clair, le contraste entre os et shimmer disparaît : passez le fond des os à rgba(0,0,0,.06) et le pic du shimmer à rgba(0,0,0,.12).

Accessibilité

  • prefers-reduced-motion absent. Mesuré avec l'émulation reduce de Playwright : animationPlayState reste à running sur les dix os. Ajoutez @media (prefers-reduced-motion: reduce) { .skel-bone::after, .skel-bone-circle::after { animation: none; } } — les os restent visibles (fond à 8 %), seul le défilement s'arrête.
  • Le squelette est un indicateur de chargement : le code ne porte ni role="status", ni aria-busy, ni aria-live, ni texte alternatif. Enveloppez .profile-skel dans un <div role="status" aria-label="Chargement du profil…">, ou posez ces attributs sur le conteneur parent qui remplacera le squelette par le contenu réel.
  • Tous les os sont des div vides, non focalisables. Posez aria-hidden="true" sur .profile-skel si le role="status" est porté par un parent.
  • La largeur est fixée à 260 px en dur. Sur une colonne plus étroite — mobile en deçà de 280 px — le squelette déborde. Remplacez width: 260px par width: min(260px, 100%) et ajustez les largeurs des os en pourcentage ou en max-width.

Compatibilité navigateur

CSS pur : requiert @keyframes, animation, linear-gradient, background-size, flexbox et les pseudo-éléments ::after. Zéro JavaScript, zéro dépendance.

Chrome 49+✓ Complet
Firefox 52+✓ Complet
Safari 9+✓ Complet
Edge 15+✓ Complet
Mobile iOS 9+✓ Complet
Android Chrome 49+✓ Complet

Sans CSS (mail HTML, lecteur RSS), les os disparaissent : la zone est vide. Sans @keyframes (IE 9 et avant), les os s'affichent en gris fixe sans défilement — un placeholder statique lisible. Sans flexbox (IE 9 et avant), la colonne et la rangée de statistiques perdent leur mise en page.

Le code

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

index.html — structure
<div class="profile-skel">
  <div class="skel-bone-circle profile-skel-avatar"></div>
  <div class="skel-bone profile-skel-name"></div>
  <div class="skel-bone profile-skel-bio1"></div>
  <div class="skel-bone profile-skel-bio2"></div>
  <div class="profile-skel-stats">
    <div class="profile-skel-stat">
      <div class="skel-bone profile-skel-stat-num"></div>
      <div class="skel-bone profile-skel-stat-label"></div>
    </div>
    <div class="profile-skel-stat">
      <div class="skel-bone profile-skel-stat-num"></div>
      <div class="skel-bone profile-skel-stat-label"></div>
    </div>
    <!-- … 1 autre .profile-skel-stat (3 au total) -->
  </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
Taille de l'avatar (CSS — .profile-skel-avatar) 80×80 px Taille du cercle. Les deux dimensions et le border-radius: 50% sont liées : gardez-les égales. 64 px convient à une fiche compacte ; 96 px à un profil pleine page.
Largeur du nom (CSS — .profile-skel-name) 130 px × 16 px La largeur suggère la longueur du pseudo ou du nom complet. 100 px pour un pseudo court ; 180 px pour un nom long. La hauteur de 16 px correspond à un texte de corps courant.
Largeurs des lignes de bio (CSS — .profile-skel-bio1, .profile-skel-bio2) 200 px / 160 px L'asymétrie (200/160) simule la coupure naturelle d'une phrase. Deux lignes égales paraissent artificielles. Supprimez .profile-skel-bio2 si la bio tient sur une seule ligne.
Durée du shimmer (CSS — animation: 1.8s) 1,8 s Vitesse du balayage. 1,2 s = sentiment d'urgence ; 2,4 s = attente assumée. En dessous de 1 s, le défilement devient agité.
Fond de base des os (CSS — rgba(255,255,255,.08)) rgba(255,255,255,.08) Couleur des rectangles et du cercle. Sur fond clair, passez à rgba(0,0,0,.07). Sur fond coloré, utilisez la couleur dominante de la page à 10–15 % d'opacité.
Pic du shimmer (CSS — rgba(255,255,255,.1) dans le dégradé) rgba(255,255,255,.10) Luminosité de la bande lumineuse. Augmenter l'écart avec le fond de base (ex. .18) rend le balayage plus visible. Sur fond clair, remplacez par rgba(255,255,255,.9).
Nombre de blocs statistiques (.profile-skel-stat) 3 Retirez un .profile-skel-stat pour deux métriques (publications, abonnés), ou ajoutez-en un quatrième si la page affiche quatre compteurs. Le flex parent les répartit automatiquement.

FAQ

Card Skeleton représente une carte de contenu : petit avatar, titre, sous-titre, image horizontale et quelques lignes de corps — une unité de liste ou de grille. Profile Skeleton représente une page ou une section dédiée à une personne : grand cercle centré (80 px, le double du card skeleton), deux lignes de bio distinctes et une rangée de métriques équiréparties. L'usage diffère : la carte skeleton est répétée dans un flux, le profil skeleton est unique et centré à l'écran. En code, Card Skeleton inclut du JavaScript (pour la transition squelette → contenu) et une image rectangulaire ; Profile Skeleton est CSS pur.
Oui : ajoutez un animation-delay par os. Exemple : nom 0 s, bio1 0,1 s, bio2 0,2 s, stats 0,3 s. La bande lumineuse descend alors de haut en bas, comme si elle balayait le profil. Un court décalage (0,1 s) donne l'impression d'un scan ; un décalage plus long (0,3–0,5 s) crée une vague lente. L'animation synchrone livrée est plus discrète et n'attire pas l'œil sur un seul os à la fois.
Remplacez width: 260px sur .profile-skel par width: 100%; max-width: 260px, et passez les largeurs fixes des os en pourcentages : 50 % pour le nom, 77 % pour la bio1, 62 % pour la bio2. La rangée de statistiques est déjà en flex — vérifiez seulement que .profile-skel-stats reste en flex-wrap: nowrap sur mobile (trois colonnes étroites) ou passez à flex-wrap: wrap; gap: 12px pour trois blocs indépendants.