gallery lightbox overlay images dialog gallery lightbox overlay dialog images photos zoom grid image gallery with lightbox photo gallery with overlay zoom
Gallery Lightbox
Fetch pattern JSON:
curl https://webspire.de/patterns/gallery/lightbox.json lightbox.html
<section class="ws-gallery bg-[var(--ws-gallery-bg)] py-20">
<div class="mx-auto max-w-7xl px-6">
<div class="text-center">
<h2 class="text-3xl font-bold tracking-tight text-[var(--ws-gallery-text)] sm:text-4xl">Our work</h2>
<p class="mt-3 text-lg text-[var(--ws-gallery-text-soft)]">A selection of recent projects and case studies.</p>
</div>
<div class="mt-12 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
<button type="button" class="group overflow-hidden rounded-xl focus:outline-none focus:ring-2 focus:ring-[var(--ws-gallery-border)] focus:ring-offset-2" onclick="this.closest('section').querySelector('#lightbox-1').showModal()">
<div class="flex aspect-[3/2] w-full items-center justify-center bg-gradient-to-br from-indigo-200 to-indigo-300 transition duration-300 group-hover:scale-105" aria-label="Project 1">
<svg class="h-8 w-8 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
</button>
<button type="button" class="group overflow-hidden rounded-xl focus:outline-none focus:ring-2 focus:ring-[var(--ws-gallery-border)] focus:ring-offset-2" onclick="this.closest('section').querySelector('#lightbox-2').showModal()">
<div class="flex aspect-[3/2] w-full items-center justify-center bg-gradient-to-tr from-emerald-200 to-emerald-300 transition duration-300 group-hover:scale-105" aria-label="Project 2">
<svg class="h-8 w-8 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
</button>
<button type="button" class="group overflow-hidden rounded-xl focus:outline-none focus:ring-2 focus:ring-[var(--ws-gallery-border)] focus:ring-offset-2" onclick="this.closest('section').querySelector('#lightbox-3').showModal()">
<div class="flex aspect-[3/2] w-full items-center justify-center bg-gradient-to-bl from-amber-200 to-amber-300 transition duration-300 group-hover:scale-105" aria-label="Project 3">
<svg class="h-8 w-8 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
</button>
<button type="button" class="group overflow-hidden rounded-xl focus:outline-none focus:ring-2 focus:ring-[var(--ws-gallery-border)] focus:ring-offset-2" onclick="this.closest('section').querySelector('#lightbox-4').showModal()">
<div class="flex aspect-[3/2] w-full items-center justify-center bg-gradient-to-tl from-rose-200 to-rose-300 transition duration-300 group-hover:scale-105" aria-label="Project 4">
<svg class="h-8 w-8 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
</button>
<button type="button" class="group overflow-hidden rounded-xl focus:outline-none focus:ring-2 focus:ring-[var(--ws-gallery-border)] focus:ring-offset-2" onclick="this.closest('section').querySelector('#lightbox-5').showModal()">
<div class="flex aspect-[3/2] w-full items-center justify-center bg-gradient-to-r from-violet-200 to-violet-300 transition duration-300 group-hover:scale-105" aria-label="Project 5">
<svg class="h-8 w-8 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
</button>
<button type="button" class="group overflow-hidden rounded-xl focus:outline-none focus:ring-2 focus:ring-[var(--ws-gallery-border)] focus:ring-offset-2" onclick="this.closest('section').querySelector('#lightbox-6').showModal()">
<div class="flex aspect-[3/2] w-full items-center justify-center bg-gradient-to-l from-sky-200 to-sky-300 transition duration-300 group-hover:scale-105" aria-label="Project 6">
<svg class="h-8 w-8 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
</button>
</div>
<!-- Lightbox dialogs -->
<dialog id="lightbox-1" class="max-h-[90vh] max-w-4xl rounded-2xl bg-transparent p-0 backdrop:bg-black/80" onclick="if(event.target===this)this.close()">
<div class="relative">
<div class="flex aspect-[3/2] w-[800px] max-w-[90vw] items-center justify-center rounded-2xl bg-gradient-to-br from-indigo-200 to-indigo-300" aria-label="Project 1">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
<button onclick="this.closest('dialog').close()" class="absolute right-3 top-3 rounded-full bg-black/50 p-2 text-white transition hover:bg-black/70">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
</button>
</div>
</dialog>
<dialog id="lightbox-2" class="max-h-[90vh] max-w-4xl rounded-2xl bg-transparent p-0 backdrop:bg-black/80" onclick="if(event.target===this)this.close()">
<div class="relative">
<div class="flex aspect-[3/2] w-[800px] max-w-[90vw] items-center justify-center rounded-2xl bg-gradient-to-tr from-emerald-200 to-emerald-300" aria-label="Project 2">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
<button onclick="this.closest('dialog').close()" class="absolute right-3 top-3 rounded-full bg-black/50 p-2 text-white transition hover:bg-black/70">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
</button>
</div>
</dialog>
<dialog id="lightbox-3" class="max-h-[90vh] max-w-4xl rounded-2xl bg-transparent p-0 backdrop:bg-black/80" onclick="if(event.target===this)this.close()">
<div class="relative">
<div class="flex aspect-[3/2] w-[800px] max-w-[90vw] items-center justify-center rounded-2xl bg-gradient-to-bl from-amber-200 to-amber-300" aria-label="Project 3">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
<button onclick="this.closest('dialog').close()" class="absolute right-3 top-3 rounded-full bg-black/50 p-2 text-white transition hover:bg-black/70">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
</button>
</div>
</dialog>
<dialog id="lightbox-4" class="max-h-[90vh] max-w-4xl rounded-2xl bg-transparent p-0 backdrop:bg-black/80" onclick="if(event.target===this)this.close()">
<div class="relative">
<div class="flex aspect-[3/2] w-[800px] max-w-[90vw] items-center justify-center rounded-2xl bg-gradient-to-tl from-rose-200 to-rose-300" aria-label="Project 4">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
<button onclick="this.closest('dialog').close()" class="absolute right-3 top-3 rounded-full bg-black/50 p-2 text-white transition hover:bg-black/70">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
</button>
</div>
</dialog>
<dialog id="lightbox-5" class="max-h-[90vh] max-w-4xl rounded-2xl bg-transparent p-0 backdrop:bg-black/80" onclick="if(event.target===this)this.close()">
<div class="relative">
<div class="flex aspect-[3/2] w-[800px] max-w-[90vw] items-center justify-center rounded-2xl bg-gradient-to-r from-violet-200 to-violet-300" aria-label="Project 5">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
<button onclick="this.closest('dialog').close()" class="absolute right-3 top-3 rounded-full bg-black/50 p-2 text-white transition hover:bg-black/70">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
</button>
</div>
</dialog>
<dialog id="lightbox-6" class="max-h-[90vh] max-w-4xl rounded-2xl bg-transparent p-0 backdrop:bg-black/80" onclick="if(event.target===this)this.close()">
<div class="relative">
<div class="flex aspect-[3/2] w-[800px] max-w-[90vw] items-center justify-center rounded-2xl bg-gradient-to-l from-sky-200 to-sky-300" aria-label="Project 6">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z" /></svg>
</div>
<button onclick="this.closest('dialog').close()" class="absolute right-3 top-3 rounded-full bg-black/50 p-2 text-white transition hover:bg-black/70">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
</button>
</div>
</dialog>
</div>
</section>
Details
Responsive Dark Mode Tailwind Only SSR Safe Copy & Paste Requires JS
Stable Published
gallerylightboxoverlayimagesdialog
Slots
| Name | Required | Description |
|---|---|---|
| heading | No | Optional section title. |
| grid | Yes | Responsive image grid with clickable thumbnails. |
| lightbox | Yes | Native dialog overlay for full-size image viewing. |
Responsive image gallery grid (2–3 columns) with clickable thumbnails. Clicking opens a native <dialog> lightbox overlay with the full-size image, a close button, and a dark backdrop. Uses dialog::backdrop for styling. Keyboard accessible (Escape to close).