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.
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
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-lineet.skeleton-headingsont 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 unaria-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.
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) :
<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>
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.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
@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..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.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.