682 tutoriels en ligne

Créa-blog

#100JoursPourCoder
Projet Créa-code | Formation Créa-troyes

Ressources pour développeur web

Théme de la semaine : WebDesign

Skeleton loading : Code pour un effet shimmer moderne

Temps de lecture estimé : 6 minutes
Accueil CSS3 Skeleton loading : Code pour un effet shimmer moderne

Vous cliquez sur une page… et au lieu d’un écran blanc, vous voyez apparaître des blocs gris animés, élégants, qui simulent le contenu en cours de chargement. Cette sensation de fluidité, vous la connaissez. LinkedIn, YouTube, Medium… tous utilisent ce principe. Dans ce tutoriel, vous allez comprendre comment coder un Skeleton loading avec effet shimmer, étape par étape

  • Améliorer immédiatement la perception de vitesse de votre site grâce à un Skeleton loading fluide et professionnel, qui remplace efficacement les écrans blancs ou les spinners classiques.
  • Maîtriser les bases techniques de l’effet shimmer pour créer des animations élégantes, performantes et sans aucune librairie externe.
  • Adapter ce composant à vos propres projets (blog, e-commerce, application web) afin d’offrir une expérience utilisateur moderne qui renforce la crédibilité et la qualité perçue de votre interface.

Nous allons coder un Skeleton loading avec effet shimmer, en partant d’un exemple concret. Sans framework. Juste du HTML et du CSS bien pensés. À la fin de ce tutoriel, vous serez capable de coder ceci et de l’utiliser dans vos projets web :

Nouvel article publié
Découvrez comment optimiser l’UX de votre site web avec le Skeleton loading avec effet shimmer.

Pourquoi utiliser un Skeleton loading ?

Avant même de parler de code, mettons-nous à la place de l’utilisateur.

Lorsque votre site met 1 à 2 secondes à charger un contenu (appel API, requête base de données, traitement JavaScript…), deux options s’offrent à vous :

  1. Afficher un écran vide.
  2. Afficher un indicateur de chargement intelligent.

Le Skeleton loading appartient à la deuxième catégorie.

Skeleton loading avec effet Shimmer

Contrairement à un simple spinner (le fameux rond qui tourne), il montre une structure visuelle proche du contenu final. Résultat :

  • L’utilisateur comprend ce qui va apparaître.
  • Le temps d’attente semble plus court.
  • L’expérience paraît plus fluide et professionnelle.

Et l’effet shimmer ? C’est cette petite animation lumineuse qui traverse les blocs gris. Elle donne une sensation de mouvement et indique subtilement : « Le contenu arrive ».

👉 Pour en savoir plus sur les spinner : 5 Exemples de loader CSS

À quoi ressemble notre composant ?

Nous allons créer une carte moderne composée :

  • D’un avatar circulaire
  • De trois lignes de texte simulées
  • D’un vrai contenu qui apparaîtra après chargement

L’objectif est simple :
Afficher d’abord le squelette animé, puis remplacer proprement par le contenu réel.

Comprendre la structure HTML

Commençons par la base. Voici la structure simplifiée :

<div class="card" id="card">
  <!-- Skeleton -->
  <div class="skeleton avatar"></div>
  <div class="content">
    <div class="skeleton line medium"></div>
    <div class="skeleton line full"></div>
    <div class="skeleton line short"></div>
  </div>

  <!-- Real Content -->
  <div class="real-content">
    <div class="real-header">Nouvel article publié</div>
    <div class="real-text">
      Découvrez comment optimiser votre maillage interne...
    </div>
  </div>
</div>

Prenons le temps d’analyser.

1. La carte principale

<div class="card" id="card">

Elle contient à la fois :

  • Le squelette (version en chargement)
  • Le contenu réel (version finale)

L’idée est simple : on masque l’un ou l’autre selon l’état de chargement.

2. Les blocs Skeleton

<div class="skeleton avatar"></div>
  • La classe skeleton sert de base visuelle.
  • La classe avatar définit sa forme circulaire.

Même principe pour les lignes :

<div class="skeleton line medium"></div>

On combine :

  • skeleton → style de base animé
  • line → hauteur
  • medium → largeur spécifique

C’est une approche modulaire très propre.
Vous pouvez réutiliser ces briques partout dans votre site.

3. Le contenu réel

<div class="real-content">

Ce bloc est caché au départ. Il apparaîtra une fois que la carte recevra la classe loaded.

  • On ne supprime rien du DOM.

On change simplement l’affichage via CSS. C’est élégant et performant.

Le cœur du skeleton loading : le CSS

Maintenant, entrons dans le moteur.

1. Les variables CSS : une base propre et maintenable

:root {
  --bg: #f4f6f9;
  --card-bg: #ffffff;
  --skeleton-base: #e6e8eb;
  --text: #1f2937;
  --muted: #6b7280;
  --radius: 16px;
}

Ici, on définit des variables globales.

Ainsi vous pourrez :

  • Modifier toute la palette en un seul endroit
  • Créer facilement un mode sombre
  • Harmoniser votre design

Un bon WebDesign commence toujours par une base cohérente.

👉 Tout savoir sur Les variables en CSS

2. Le style de la carte

.card {
  background: var(--card-bg);
  border-radius: var(--radius);
  padding: 24px;
  box-shadow: 0 10px 35px rgba(0,0,0,0.06);
  display: flex;
  gap: 18px;
  align-items: flex-start;
  position: relative;
  overflow: hidden;
}

Regardons les points importants :

  • display: flex → permet d’aligner avatar et contenu
  • gap → espace moderne entre éléments
  • overflow: hidden → essentiel pour l’effet shimmer (on y revient)

Le design est volontairement doux et moderne. Un Skeleton loading doit s’intégrer naturellement à votre UI.

L’effet shimmer : la magie expliquée simplement

Voici la partie la plus intéressante.

1. Le bloc de base

.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--skeleton-base);
}

On donne :

  • Une couleur grise neutre
  • Un overflow: hidden pour cacher l’animation débordante

Mais l’animation n’est pas ici…

2. Le pseudo-élément ::after

.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255,255,255,0.6),
    transparent
  );
  animation: shimmer 1.4s infinite;
}

Prenons le temps de comprendre.

  1. On ajoute une couche invisible par-dessus le bloc gris.
  2. Cette couche contient un dégradé blanc semi-transparent.

Le gradient est horizontal :

linear-gradient(90deg, transparent, blanc, transparent)

Ce qui crée une bande lumineuse.

3. L’animation

@keyframes shimmer {
  100% { transform: translateX(100%); }
}

L’animation déplace la bande lumineuse de gauche à droite.

Formation web et informatique - Alban Guillier - Formateur

Des formations informatique pour tous !

Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…

Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.

Découvrez mes formations Qui suis-je ?

Au départ :

transform: translateX(-100%);

À la fin :

transform: translateX(100%);

Résultat : Une lumière traverse le bloc en continu.

  • Et voilà votre effet shimmer.

Pas besoin de JavaScript. Juste une animation CSS propre et performante.

Gestion de l’apparition du vrai contenu

Un Skeleton loading ne sert à rien si le contenu réel n’apparaît pas proprement.

Voici la logique :

.real-content {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.4s ease, transform 0.4s ease;
  display: none;
}

On prépare le bloc pour une animation douce.

Puis :

.card.loaded .real-content {
  display: block;
  opacity: 1;
  transform: translateY(0);
}

Lorsque la carte reçoit la classe loaded :

  • Le contenu apparaît
  • Il remonte légèrement
  • L’opacité passe à 1

Effet professionnel garanti.

Et pendant ce temps :

.card.loaded .skeleton,
.card.loaded .content {
  display: none;
}

Le squelette disparaît.

Propre. Net. Sans clignotement.

Pourquoi cette technique est performante ?

Le Skeleton loading avec effet shimmer repose uniquement sur :

  • CSS
  • Pseudo-éléments
  • Transformations GPU (translate)

Aucune image. Aucune librairie. Aucun reflow lourd.

Les animations basées sur transform sont accélérées matériellement par le navigateur. Donc même sur mobile, c’est fluide.

Personnaliser votre Skeleton loading

Maintenant que vous comprenez le principe, amusez-vous.

Vous pouvez :

  • Changer la vitesse de l’animation
  • Modifier la largeur du dégradé
  • Adapter les formes (cartes produits, tableaux, commentaires)
  • Ajouter un mode sombre

Exemple pour ralentir :

animation: shimmer 2s infinite;

Envie d’un shimmer plus subtil ?

rgba(255,255,255,0.3)

Plus vous maîtrisez le CSS, plus vous pouvez affiner l’expérience.

Erreurs fréquentes à éviter

Même si le Skeleton loading paraît simple, certaines erreurs peuvent nuire à l’expérience.

Évitez :

  • Un shimmer trop rapide (effet stressant)
  • Une couleur trop contrastée
  • Un squelette qui ne correspond pas au vrai contenu
  • Une transition brutale vers le contenu final

Le but est d’améliorer la perception de vitesse, pas d’ajouter du bruit visuel.

Quand utiliser un effet shimmer ?

Le Skeleton loading avec effet shimmer est particulièrement pertinent pour :

  • Les listes d’articles
  • Les dashboards
  • Les cartes produits e-commerce
  • Les interfaces SaaS
  • Les applications web modernes

En revanche, pour un chargement ultra court (moins de 200 ms), ce n’est pas nécessaire.

Aller plus loin

Une fois que vous maîtrisez cette base, vous pouvez :

  • Déclencher le passage en loaded après une requête fetch()
  • L’utiliser avec Vue, React ou Alpine.js
  • L’adapter aux appels AJAX WordPress
  • Créer un composant réutilisable

Et là… vous passez d’un simple site web à une vraie expérience utilisateur moderne.

Le code complet avec JS pour faire apparaitre le contenu

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Skeleton Loading - Demo interactive</title>

<style>
:root {
  --bg: #f4f6f9;
  --card-bg: #ffffff;
  --skeleton-base: #e6e8eb;
  --text: #1f2937;
  --muted: #6b7280;
  --radius: 16px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 60px 20px;
  gap: 30px;
}

.wrapper {
  width: 100%;
  max-width: 720px;
}

.card {
  background: var(--card-bg);
  border-radius: var(--radius);
  padding: 24px;
  box-shadow: 0 10px 35px rgba(0,0,0,0.06);
  display: flex;
  gap: 18px;
  align-items: flex-start;
  position: relative;
  overflow: hidden;
}

/* Skeleton */
.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--skeleton-base);
}

.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255,255,255,0.6),
    transparent
  );
  animation: shimmer 1.4s infinite;
}

@keyframes shimmer {
  100% { transform: translateX(100%); }
}

.avatar {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  flex-shrink: 0;
}

.content {
  flex: 1;
  display: grid;
  gap: 12px;
}

.line {
  height: 14px;
  border-radius: 8px;
}

.line.short { width: 60%; }
.line.medium { width: 80%; }
.line.full { width: 100%; }

/* Real content */
.real-content {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.4s ease, transform 0.4s ease;
  display: none;
}

.card.loaded .real-content {
  display: block;
  opacity: 1;
  transform: translateY(0);
}

.card.loaded .skeleton,
.card.loaded .content {
  display: none;
}

.real-header {
  font-weight: 600;
  color: var(--text);
  margin-bottom: 6px;
}

.real-text {
  color: var(--muted);
  line-height: 1.5;
  font-size: 14px;
}

/* Button */
button {
  background: #111827;
  color: #fff;
  border: none;
  padding: 12px 22px;
  border-radius: 12px;
  cursor: pointer;
  font-size: 14px;
  transition: transform 0.15s ease, opacity 0.2s ease;
}

button:hover {
  transform: translateY(-2px);
  opacity: 0.9;
}

button:active {
  transform: translateY(0);
}
</style>
</head>

<body>

<div class="wrapper">
  <div class="card" id="card">
    <!-- Skeleton -->
    <div class="skeleton avatar"></div>
    <div class="content">
      <div class="skeleton line medium"></div>
      <div class="skeleton line full"></div>
      <div class="skeleton line short"></div>
    </div>

    <!-- Real Content -->
    <div class="real-content">
      <div class="real-header">Nouvel article publié</div>
      <div class="real-text">
        Découvrez comment optimiser votre maillage interne et améliorer la performance SEO de votre site.
      </div>
    </div>
  </div>
</div>

<button onclick="replay()">Rejouer l’animation</button>

<script>
function loadContent() {
  setTimeout(() => {
    document.getElementById('card').classList.add('loaded');
  }, 1800);
}

function replay() {
  const card = document.getElementById('card');
  card.classList.remove('loaded');
  void card.offsetWidth;
  loadContent();
}

loadContent();
</script>

</body>
</html>

Le Skeleton loading avec effet shimmer n’est pas qu’un effet esthétique. C’est une stratégie d’UX. Une manière intelligente de transformer un temps d’attente en expérience fluide.

Vous venez de voir qu’avec du HTML structuré, quelques variables CSS et une animation bien pensée, vous pouvez reproduire ce comportement utilisé par les plus grandes plateformes.

Ce genre de détail fait toute la différence entre un site « correct » et un site professionnel. Et maintenant que vous en maîtrisez les principes, vous pouvez l’intégrer dans vos propres projets, l’adapter, l’améliorer… et surtout impressionner vos utilisateurs.

La prochaine fois qu’un contenu mettra une seconde à charger, vous ne laisserez plus jamais un écran vide.