SnippetUI

Skeleton Loader

Interface utilisateur squelette avec de riches animations chatoyantes affichées pendant le chargement du contenu

HTMLCSS

Un composant d’interface utilisateur d’espace réservé (squelettique) qui s’affiche jusqu’à ce que le contenu soit chargé. L’ajout d’une animation chatoyante dans laquelle la lumière fonctionne fluidement a pour effet de rendre le temps d’attente de l’utilisateur psychologiquement plus court.

Il a été créé en supposant une présentation de type carte fréquemment utilisée dans les applications Web modernes.

Composant de la carte squelette

<div class="skeleton-card">
  <div class="skeleton-header">
    <div class="skeleton-avatar skeleton-shimmer"></div>
    <div class="skeleton-title-container">
      <div class="skeleton-title skeleton-shimmer"></div>
      <div class="skeleton-subtitle skeleton-shimmer"></div>
    </div>
  </div>
  <div class="skeleton-body">
    <div class="skeleton-text skeleton-shimmer"></div>
    <div class="skeleton-text skeleton-shimmer"></div>
    <div class="skeleton-text short skeleton-shimmer"></div>
  </div>
</div>
/* Style général de la carte */
.skeleton-card {
  width: 100%;
  max-width: 360px;
  background: #ffffff;
  border-radius: 16px;
  padding: 24px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* Compatible mode sombre */
[data-theme="dark"] .skeleton-card {
  background: #1a1a2e;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}

/* Skeleton base and animation origin */
.skeleton-shimmer {
  background-color: #e0e0e0;
  border-radius: 8px;
  position: relative;
  overflow: hidden;
}

[data-theme="dark"] .skeleton-shimmer {
  background-color: #2a2a40;
}

/* Effet Shimmer (feux de circulation) */
.skeleton-shimmer::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  transform: translateX(-100%);
  background-image: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0,
    rgba(255, 255, 255, 0.4) 20%,
    rgba(255, 255, 255, 0.6) 60%,
    rgba(255, 255, 255, 0)
  );
  animation: shimmer 2s infinite;
}

[data-theme="dark"] .skeleton-shimmer::after {
  background-image: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0,
    rgba(255, 255, 255, 0.05) 20%,
    rgba(255, 255, 255, 0.1) 60%,
    rgba(255, 255, 255, 0)
  );
}

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

/* Partie en-tête (avatar et titre) */
.skeleton-header {
  display: flex;
  align-items: center;
  gap: 16px;
}

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

.skeleton-title-container {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.skeleton-title {
  height: 16px;
  width: 60%;
}

.skeleton-subtitle {
  height: 12px;
  width: 40%;
}

/* Body section (text lines) */
.skeleton-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.skeleton-text {
  height: 14px;
  width: 100%;
}

.skeleton-text.short {
  width: 80%;
}