Navigation✨ Premium

Skeleton Text

Lignes fantômes animées par un reflet lumineux CSS pur — le shimmer matérialise un état de chargement élégant en quelques classes, sans une ligne de JavaScript.

CSSLoadingPlaceholder

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

Résultats de recherche — Titres et extraits en attente de l'API — Skeleton Text exemple 1

① Résultats de recherche — Titres et extraits en attente de l'API

QuandUn moteur de recherche interne ou une SPA affiche les résultats pendant que l'API répond à la requête — chaque entrée se réduit à un heading fantôme et deux lignes d'extrait, sans image ni avatar.
PourquoiSeules des barres de texte à largeur décroissante, sans aucun bloc image, exposent la spécificité « texte pur » de l'effet : le shimmer balaie une surface typographique dense (titre de lien + extrait × 5 résultats) que fx-0469 ne couvrirait pas — il n'y a rien d'autre à habiller que du contenu textuel structuré.
RéglagesHeading à 14 px avec teinte bleue (rgba(100,150,255,.18) au pic) pour évoquer un lien, deux lignes d'extrait à 100 % et 84 % (hauteur 9 px), animation-delay échelonné de 0,1 s par résultat, 9 px de gap entre résultats, zéro bloc image.
Page d'article — Corps de texte en cours de récupération — Skeleton Text exemple 2

② Page d'article — Corps de texte en cours de récupération

QuandL'article est récupéré côté client (fetch, lazy hydration, ISR Next.js) — le skeleton occupe toute la colonne de lecture avant que le Markdown soit parsé et rendu.
PourquoiDes lignes à largeur décroissante sur toute la hauteur de la colonne reproduisent fidèlement la densité visuelle d'un texte long. Le shimmer maintient la perception d'activité sur une attente pouvant dépasser 1–2 secondes.
RéglagesHeading à 50 % de largeur (24 px), 2–3 blocs .skeleton-paragraph enchaînés avec margin-bottom: 24px entre eux, max-width: 660px aligné sur la colonne éditoriale.
Tableau de résultats — Lignes en attente de réponse API — Skeleton Text exemple 3

③ Tableau de résultats — Lignes en attente de réponse API

QuandUn tableau d'administration ou de reporting affiche des lignes skeleton pendant que la requête SQL ou l'appel REST renvoie ses données (recherche, filtrage, pagination).
PourquoiDes lignes à hauteur constante (12 px) et sans heading reproduisent exactement la densité d'un tableau de données — l'utilisateur comprend immédiatement qu'il attend des lignes de données, pas une image ou une card.
RéglagesSupprimer .skeleton-heading, aligner les .skeleton-line en colonne directement dans le conteneur, fixer height: 12px et réduire margin-bottom à 6 px pour la densité d'un tableau.

Comment ça marche

L'animation repose sur un unique @keyframes shimmer qui déplace background-position de 200% 0 à -200% 0. Chaque ligne porte un dégradé linéaire horizontal dimensionné à 200 % de la largeur de l'élément (arrêts de couleur à 25 %, 50 %, 75 %) — quand la position défile, la zone lumineuse du centre traverse la surface visible de droite à gauche, simulant un reflet qui balaie le contenu en attente.

La distinction visuelle entre titre et lignes de corps est gérée par deux couches CSS. Le bloc .skeleton-heading mesure 24 px de haut avec un pic d'opacité à 0,15 au centre du dégradé (contre 0,10 pour les lignes de texte ordinaires) — il est perceptivement plus lourd, comme un vrai titre. Les lignes dans .skeleton-paragraph héritent de hauteur 14 px et d'espacement 10 px via un sélecteur plus spécifique, qui écrase silencieusement les valeurs de base sans dupliquer le reste des règles.

Les largeurs décroissantes des lignes (100 %, 95 %, 85 %, 40 % pour la dernière) imitent la longueur naturelle des phrases réelles : la plupart des lignes remplissent presque toute la largeur, la dernière est courte comme un paragraphe qui n'arrive pas au bout. Ce détail est géré par nth-child — ajouter ou retirer un .skeleton-line ne nécessite aucune modification du CSS.

La cascade temporelle est obtenue par des animation-delay échelonnés : 0,1 s pour la première ligne, 0,2 s pour la deuxième, 0,3 s pour la troisième. Le reflet ne traverse pas toutes les lignes simultanément ; il descend progressivement, donnant l'impression d'un scan actif qui rend l'attente moins inerte. Aucun JavaScript n'est requis — tout est déclaratif et fonctionne dès que les classes sont présentes dans le DOM.

Accessibilité

  • prefers-reduced-motion absent du code — le shimmer s'anime en continu indépendamment de la préférence système. Recommandation : ajouter @media (prefers-reduced-motion: reduce) { .skeleton-line, .skeleton-heading { animation: none; } } pour la conformité WCAG 2.3.3.
  • Les <div> .skeleton-line et .skeleton-heading sont entièrement vides (pas de texte, pas de rôle interactif) — les lecteurs d'écran ne les vocalisent pas par défaut.
  • Aucun attribut ARIA n'est défini dans le code fourni. Pour signaler un chargement, ajouter aria-busy="true" sur le conteneur parent jusqu'à ce que le vrai contenu soit injecté, et un aria-label="Chargement en cours" pour contextualiser l'état.
  • Le contraste des lignes est intentionnellement faible (opacités 5 %–15 %) — illisible comme texte, ce qui est le comportement attendu d'un placeholder visuel purement décoratif.
  • Aucune interaction clavier ou souris n'est gérée : l'effet est passif et n'intègre aucun élément focusable ni cliquable.

Compatibilité navigateur

Repose uniquement sur des animations CSS et des dégradés linéaires — technologies disponibles dans tous les navigateurs modernes depuis 2014, zéro dépendance externe.

Chrome 43+✓ Complet
Firefox 16+✓ Complet
Safari 9+✓ Complet
Edge 14+✓ Complet
Mobile iOS✓ Complet
Android Chrome✓ Complet

Si les animations CSS ne sont pas supportées (navigateur très ancien), les lignes s'affichent comme des blocs statiques semi-transparents — la structure de chargement reste compréhensible sans mouvement.

Le code

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

index.html — structure
<div class="skeleton-text-demo">
  <div class="skeleton-heading"></div>
  <div class="skeleton-paragraph">
    <div class="skeleton-line"></div>
    <div class="skeleton-line"></div>
    <div class="skeleton-line"></div>
    <div class="skeleton-line"></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.5s) 1.5s Durée du cycle shimmer sur .skeleton-line et .skeleton-heading. 1 s = réactif, 2,5 s = très lent — aligner sur la durée réelle de chargement attendue pour éviter la répétition perceptible.
opacité pic du gradient (.1 / .15) 0,10 lignes · 0,15 titre Éclat maximal du reflet (arrêt à 50 %). Augmenter à 0,25–0,35 pour un fond clair ou pour renforcer la visibilité du shimmer dans un thème light.
opacité base du gradient (.05) 0,05 Couleur de fond des lignes au repos (arrêts à 25 % et 75 %). Monter à 0,08–0,12 pour un skeleton plus visible sur un fond très sombre ou coloré.
animation-delay cascade (0.1s, 0.2s, 0.3s) 0,1 s par ligne (nth-child) Décalage entre chaque ligne. Mettre à 0 s pour un shimmer synchrone sur toutes les lignes ; augmenter à 0,25 s pour accentuer l'effet de scan descendant.
height des lignes (12px / 14px) 12 px · 14 px dans .skeleton-paragraph Hauteur des barres de texte. Utiliser 10 px pour un tableau dense, 16–18 px pour imiter un corps de texte large (mobile, grande typographie).
height du heading (24px) 24 px Hauteur de .skeleton-heading. Adapter à la taille réelle du titre remplacé : h1 → 32–36 px, h2 → 26 px, h3 → 18–20 px.
max-width du bloc (300px) 300 px Largeur maximale de .skeleton-text-demo. Passer à 100% pour remplir un conteneur fluide (colonne éditoriale pleine largeur, card responsive).
border-radius (4px / 6px) 4 px lignes · 6 px heading Arrondi des barres. 2 px pour un rendu tableauté, 999 px pour des pilules arrondies — à harmoniser avec la typographie et les boutons de l'UI.

FAQ

Non, l'effet est 100 % CSS. L'animation shimmer est entièrement déclarée via @keyframes et la propriété animation. Aucun script n'est requis : copiez le HTML et le CSS, l'animation démarre seule. Compatible avec tous les frameworks (React, Vue, Svelte, Angular) — ajoutez les classes sur n'importe quel élément, y compris des composants générés dynamiquement.
Répétez le bloc .skeleton-text-demo autant de fois que nécessaire — le CSS ne repose sur aucun état global, chaque instance est autonome. Pour un tableau, supprimez .skeleton-heading et disposez directement plusieurs .skeleton-line en colonne dans un <div> conteneur, en réduisant margin-bottom à 6–8 px pour la densité d'une ligne de tableau.
Le code fourni ne contient pas de règle prefers-reduced-motion. Pour la conformité WCAG 2.3.3, ajoutez : @media (prefers-reduced-motion: reduce) { .skeleton-line, .skeleton-heading { animation: none; } }. Les barres restent visibles comme blocs statiques — la structure de chargement est compréhensible sans animation.