Chargement✨ Premium

Image Grid Skeleton

Grille 2 × 2 de 260 × 260 px : quatre plages 125 × 125 px, arrondi 12 px, shimmer ease-in-out de 1,8 s sur ::after. Cascade 0 / 0,15 / 0,30 / 0,45 s portée par la propriété personnalisée --skel-delay, posée sur chaque cellule et héritée par le pseudo-élément — les quatre tuiles s'allument l'une après l'autre.

CSSGridImages

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

Sélecteur de variante — quatre visuels produit en cours de chargement — Image Grid Skeleton exemple 1

① Sélecteur de variante — quatre visuels produit en cours de chargement

QuandPanneau latéral ou modale de configuration d'un produit : l'acheteur choisit une couleur parmi quatre options, chacune représentée par un carré d'image.
PourquoiLa grille 2 × 2 de carrés homogènes correspond exactement à quatre visuels de même taille. L'arrondi 12 px convient à une interface de shopping. Quatre couleurs n'ont pas d'ordre entre elles : ici, on retire les attributs style="--skel-delay: …" pour que les quatre plages brillent ensemble — un shimmer synchrone est moins perturbant qu'une cascade quand l'acheteur ne hiérarchise pas les options.
RéglagesLargeur réduite à 200px → cellules ~95 × 95 px, arrondi 8px, durée 1,4s, attributs --skel-delay retirés (shimmer synchrone).
Dernières publications — widget Instagram dans un pied de page — Image Grid Skeleton exemple 2

② Dernières publications — widget Instagram dans un pied de page

QuandPied de page ou barre latérale d'un site de mode ou de restaurant : un bloc « Suivez-nous » affiche les quatre dernières photos avant qu'elles soient reçues du réseau.
PourquoiLes photos Instagram sont toujours carrées ; quatre cellules 2 × 2 dans 260 px reproduisent exactement la mise en page attendue. Le shimmer sobre évite de détourner l'œil de la navigation pendant le chargement.
RéglagesArrondi 0 ou 4px pour coller au rendu natif, fond légèrement plus chaud rgba(255,200,150,.06).
Miniature de couverture — quatre images extraites de la vidéo arrivent l'une après l'autre — Image Grid Skeleton exemple 3

③ Miniature de couverture — quatre images extraites de la vidéo arrivent l'une après l'autre

QuandÉtape « Miniature » de la publication d'une vidéo : l'éditeur tire quatre images du montage (0:04, 0:31, 1:12, 2:05) et les propose comme couverture. Elles sont extraites dans l'ordre de la vidéo et s'affichent à mesure qu'elles sont prêtes.
PourquoiQuatre propositions de même format qui arrivent dans un ordre connu : c'est exactement ce que dit la cascade 0 / 0,15 / 0,30 / 0,45 s — la première cellule s'allume avant la deuxième, qui précède la troisième… le décalage rejoue l'ordre d'extraction. Un spinner ou une barre annonceraient « ça charge » sans dire ni combien, ni dans quel ordre ; une liste de lignes ne dirait pas « ce sont des images ». Quatre carrés de 125 px en 2 × 2 réservent la place exacte de chaque vignette : rien ne saute quand elles arrivent.
RéglagesLargeur par défaut 260px (cellules 125 × 125 px), arrondi 12 px, cascade par défaut (--skel-delay 0 / 0,15 / 0,30 / 0,45 s), shimmer relevé à rgba(255,255,255,.18) pour que le décalage entre cellules se lise.

Comment ça marche

Structure. .grid-skel est une grille CSS deux colonnes (grid-template-columns: 1fr 1fr, gap: 10px, width: 260px) : les quatre cellules font donc (260 − 10) ÷ 2 = 125 px de large chacune. Leur hauteur est dictée par aspect-ratio: 1/1 → 125 × 125 px. La grille mesure 260 × 260 px au total. Chaque cellule est un div.skel-bone.grid-skel-img : fond rgba(255,255,255,.08), border-radius: 12px (qui écrase les 6 px de la classe parente), position: relative et overflow: hidden pour contenir le pseudo-élément. Aucun JS : l'effet est entièrement CSS.

Shimmer. L'animation repose sur ::after (absolu, inset: 0, content: ""). Son fond est un linear-gradient(90deg, transparent 0, rgba(255,255,255,.1) 50%, transparent 100%) déclaré avec background-size: 200% 100% — le dégradé est deux fois plus large que la cellule. L'@keyframe shimmerSlide déplace la background-position de -200% 0 à 200% 0 : la bande lumineuse entre par la gauche, traverse la cellule et ressort par la droite. Durée : 1,8 s ease-in-out, infini. Le pic de lumière à 10 % d'opacité reste sobre sur le fond gris à 8 %.

Cascade — et pourquoi elle passe par une propriété personnalisée. Le HTML livré porte style="--skel-delay: .15s", .3s et .45s sur trois des quatre cellules (la première n'a pas d'attribut), et .skel-bone::after déclare animation-delay: var(--skel-delay, 0s). Ce détour est nécessaire : l'animation vit sur le pseudo-élément, or un animation-delay posé sur un élément ne se propage pas à son ::after — les propriétés d'animation ne sont pas héritées, chaque pseudo-élément a les siennes. Une propriété CSS personnalisée, elle, est héritée par les pseudo-éléments : var(--skel-delay, 0s) lit la valeur inscrite sur la cellule parente et retombe sur 0s quand rien n'est posé. Mesuré avec l'API getAnimations() : les quatre pseudo-éléments rapportent delay = 0 / 150 / 300 / 450 ms et quatre background-position distinctes au même instant — la cascade est bien visible. Contre-épreuve : un style="animation-delay: .15s" écrit directement sur la cellule laisse les quatre ::after à delay=0ms et à la même position — synchronie parfaite, cascade absente.

Accessibilité

  • prefers-reduced-motion absent du code. Confirmé : aucune règle @media (prefers-reduced-motion: reduce) dans le CSS vendu. Les quatre shimmers tournent en continu quelle que soit la préférence système. Ajoutez @media (prefers-reduced-motion: reduce) { .skel-bone::after { animation: none } } — la plage grise reste visible et signale toujours le chargement, sans mouvement.
  • Un skeleton screen est un indicateur de chargement fonctionnel, pas un élément purement décoratif. Le conteneur .grid-skel devrait porter role="status" et aria-label="Chargement des images…" pour qu'un lecteur d'écran annonce l'état d'attente. Retirez ces attributs et remplacez-les par aria-hidden="true" une fois le contenu réel inséré.
  • Les cellules sont des div vides : aucun texte, aucune icône. Posez aria-hidden="true" sur chaque .skel-bone pour que l'arbre d'accessibilité ne contienne que l'annonce du conteneur.
  • Intégration. La grille a une width fixe (260 px) : sur mobile étroit, ajoutez max-width: 100% sur .grid-skel et grid-template-columns: 1fr 1fr s'adaptera automatiquement via aspect-ratio: 1/1.

Compatibilité navigateur

CSS pur, zéro JS. Requiert CSS Grid (2019), aspect-ratio (2021), inset (2021), les propriétés personnalisées var() (2017) et @keyframes/animation (2012).

Chrome 88+✓ Complet
Firefox 89+✓ Complet
Safari 15+✓ Complet
Edge 88+✓ Complet
Mobile iOS 15+✓ Complet
Android Chrome 88+✓ Complet

Sans aspect-ratio (Safari 14 et antérieurs) : les cellules s'aplatissent à hauteur 0 et deviennent invisibles. Repli : ajouter height: 125px sur .grid-skel-img. Sans inset : remplacer par top:0;right:0;bottom:0;left:0 sur .skel-bone::after.

Le code

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

index.html — structure
<div class="grid-skel">
  <div class="skel-bone grid-skel-img"></div>
  <div class="skel-bone grid-skel-img" style="--skel-delay: .15s"></div>
  <div class="skel-bone grid-skel-img" style="--skel-delay: .3s"></div>
  <div class="skel-bone grid-skel-img" style="--skel-delay: .45s"></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
Durée du shimmer (CSS — .skel-bone::after { animation: 1.8s ease-in-out infinite … shimmerSlide }) 1,8 s Vitesse de passage de la bande lumineuse. 1 s = shimmer vif ; 2,5 s = ondulation lente et discrète.
Largeur de la grille (CSS — .grid-skel { width: 260px }) 260 px Détermine la taille des cellules : (largeur − gap) ÷ 2. 200px → ~95 × 95 px ; 340px → ~165 × 165 px. Ajoutez max-width: 100% pour les mises en page fluides.
Goutière (CSS — .grid-skel { gap: 10px }) 10 px Espace entre les quatre cellules. 6 px pour resserrer ; 16 px pour un espacement carte.
Arrondi (CSS — .grid-skel-img { border-radius: 12px }) 12 px 12 px pour des coins légèrement doux. 0 pour des carrés nets (photos plein format) ; 50% pour des cercles (avatars 4 en grille).
Fond des plages (CSS — .skel-bone { background: rgba(255,255,255,.08) }) rgba(255,255,255,.08) Fond visible au repos et entre les passages du shimmer. Sur un fond clair, passer à rgba(0,0,0,.08).
Intensité du shimmer (CSS — rgba(255,255,255,.1) dans le dégradé de .skel-bone::after) rgba(255,255,255,.1) .06 = très discret ; .18 = bande nettement visible. Gardez un rapport ≥ 2:1 avec la valeur du fond.
Cascade (HTML — style="--skel-delay: .15s" sur chaque cellule, lu par .skel-bone::after { animation-delay: var(--skel-delay, 0s) }) 0 / 0,15 / 0,30 / 0,45 s (la première cellule n'a pas d'attribut : repli 0s) Écart entre l'allumage des cellules. Retirer les attributs → shimmer synchrone ; .25s, .5s, .75s → cascade plus marquée. Passez toujours par la propriété personnalisée : un animation-delay écrit directement sur la cellule ne se propage pas à ::after, alors qu'une propriété personnalisée en est héritée.

FAQ

Parce que l'animation shimmerSlide est déclarée sur ::after, et qu'un pseudo-élément a ses propres propriétés d'animation : un animation-delay posé sur la cellule parente ne lui est pas transmis — les propriétés animation-* ne sont pas héritées. Les propriétés CSS personnalisées, elles, le sont : .skel-bone::after { animation-delay: var(--skel-delay, 0s) } lit donc la valeur inscrite dans style="--skel-delay: .15s" sur la cellule, et retombe sur 0s pour la première, qui n'a pas d'attribut. Contre-épreuve avec getAnimations() : avec style="animation-delay: .15s" sur la cellule à la place, les quatre pseudo-éléments restent à delay=0ms et brillent en parfaite synchronie. Si vous générez la grille en boucle, écrivez style="--skel-delay: …" sur chaque cellule avec une valeur croissante.
fx-0469 Skeleton Card simule une carte portrait : un rectangle d'image en haut, suivi de deux lignes de texte en dessous — un seul élément, avec hiérarchie image + titre. fx-0441 Image Grid Skeleton simule une galerie : quatre carrés homogènes, sans texte, organisés en 2 × 2. L'un signale le chargement d'un contenu mixte (photo + description) ; l'autre, le chargement d'une grille d'images pure. Ils ne sont pas interchangeables.
Oui : l'effet n'utilise pas de JS. Pour une 3 × 3, ajoutez 5 éléments .skel-bone.grid-skel-img (9 au total) et passez grid-template-columns à 1fr 1fr 1fr. Pour une 4 × 2, ajoutez 4 éléments et passez à 1fr 1fr 1fr 1fr. Ajustez width en conséquence — ex. 370px pour 4 colonnes à ~85px avec gap de 10px. aspect-ratio: 1/1 adapte automatiquement la hauteur. Prolongez la cascade en posant --skel-delay en croissant sur les nouvelles cellules (.6s, .75s…), ou retirez les attributs pour un shimmer synchrone.