Zoom Lightbox
La photo grandit exactement depuis la vignette cliquée jusqu'au centre de l'écran, puis repart s'y ranger à la fermeture.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Galerie comprend 44 effets, dont 6 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Technique dite FLIP. Au clic sur un bouton .zlb-thumb, le script ouvre le <dialog>, attend que la grande image connaisse sa taille (img.decode()), puis mesure deux rectangles : celui de la vignette et celui de l'image à sa place finale. Il en déduit un décalage et une échelle, et lance avec element.animate() une animation qui part de la vignette (translate + scale) pour arriver à transform: none.
L'aller dure 400 ms avec la courbe d'origine de l'effet (cubic-bezier(0.175, 0.885, 0.32, 1.275), un petit dépassement) ; le fond noir à 90 % apparaît en fondu pendant ce temps. À la fermeture (✕, Échap ou clic sur le fond), la même animation est jouée à l'envers, en 400 ms accélérées, vers la position de la vignette à cet instant ; le dialog se ferme ensuite.
Mesuré dans Chromium, Firefox et WebKit : au départ de l'animation, le centre de l'image coïncide au pixel près avec celui de la vignette. Si la vignette et l'image n'ont pas les mêmes proportions, l'image est légèrement étirée pendant les 400 ms, puis retrouve ses proportions.
Accessibilité
- Boutons : chaque vignette est un
<button>au Tab, ouverte par Entrée ou Espace ; sonaltdevient celui de la grande image. - Dialog modal : rôle dialog et nom « Visionneuse d'images », page derrière inerte, focus sur ✕ à l'ouverture, Échap pour fermer.
- Focus rendu : il revient sur la vignette d'où l'image est partie, là où l'image vient de se ranger.
- Mouvement réduit : avec
prefers-reduced-motion: reduce, aucun zoom ni fondu ; l'image apparaît directement au centre et disparaît d'un coup. - Toucher : un toucher ouvre comme un clic. Il n'y a pas de navigation entre images dans cette visionneuse : une image par ouverture.
Compatibilité navigateur
element.animate() existe depuis Chrome 36, Firefox 48 et Safari 13.1, img.decode() depuis Chrome 64, Firefox 68 et Safari 11.1 ; le facteur limitant reste le <dialog> modal (Firefox 98, Safari 15.4) et aspect-ratio (Chrome 88). Point de départ du zoom mesuré dans Chromium 151, Firefox 153 et WebKit 26.5, avec deux galeries sur la page.
Sans img.decode(), le zoom attend l'événement load de l'image. Sans showModal(), rien ne s'ouvre et les vignettes restent de simples photos.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0173-root">
<div class="zlb-grid">
<button type="button" class="zlb-thumb" aria-haspopup="dialog"><img src="photo.jpg" alt="Dégradé cyan vers émeraude" width="600" height="400"></button>
<button type="button" class="zlb-thumb" aria-haspopup="dialog"><img src="photo.jpg" alt="Dégradé ambre vers rouge" width="600" height="400"></button>
<button type="button" class="zlb-thumb" aria-haspopup="dialog"><img src="photo.jpg" alt="Dégradé indigo vers violet" width="600" height="400"></button>
<button type="button" class="zlb-thumb" aria-haspopup="dialog"><img src="photo.jpg" alt="Dégradé violet vers cyan" width="600" height="400"></button>
</div>
<dialog class="zlb-viewer" aria-label="Visionneuse d'images">
<div class="zlb-content">
<button type="button" class="zlb-close" aria-label="Fermer"><svg>…</svg></button>
<img class="zlb-image" alt="">
</div>
</dialog>
</div>
Paiement unique, sans abonnement — le code est à toi pour toujours
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Durée du zoom (JS — CLOSE_MS) |
400 ms | Sert à l'aller, au retour et au délai avant fermeture ; ajustez aussi la transition d'opacité du CSS. |
Courbe d'ouverture (JS — easing dans zoomBetween) |
cubic-bezier(0.175, 0.885, 0.32, 1.275) |
Le dernier nombre au-dessus de 1 donne le petit rebond ; ease-out pour une arrivée sans dépassement. |
Largeur des vignettes (CSS — --zlb-thumb) |
120px | Format 3:2 ; vous pouvez aussi positionner chaque vignette librement, le zoom part toujours de sa vraie place. |
Fond (CSS — --zlb-backdrop) |
rgba(0, 0, 0, 0.9) |
Teinte du voile qui se fonce pendant le zoom. |
Arrondis (CSS — --zlb-radius, --zlb-radius-lg) |
0.5rem, 1rem | Coins de la vignette et de l'image agrandie. |
Photo pleine résolution (HTML — data-full) |
absent | Chargée à l'ouverture ; le zoom démarre quand elle est décodée. |
FAQ
.zlb-thumb le même format que vos photos pour un zoom parfaitement proportionné.element.animate() marche partout où le <dialog> marche, sans réglage.