gallery photos grid portfolio images uniform gallery photos grid portfolio images uniform camera uniform photo grid gallery simple image grid with hover effect
Photo Grid
Fetch pattern JSON:
curl https://webspire.de/patterns/gallery/grid.json grid.html
<section class="ws-gallery bg-[var(--ws-gallery-bg)] py-20">
<div class="mx-auto max-w-7xl px-6">
<div class="mx-auto max-w-2xl text-center">
<p class="text-sm font-semibold uppercase tracking-[0.18em] text-[var(--ws-gallery-text)]">Gallery</p>
<h2 class="mt-3 text-balance text-3xl font-bold tracking-tight text-[var(--ws-gallery-text)] sm:text-4xl">Photo collection</h2>
</div>
<div class="mt-12 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
<a href="#" class="group relative aspect-square overflow-hidden rounded-xl bg-[var(--ws-color-surface-alt)]">
<div class="flex h-full w-full items-center justify-center transition duration-300 group-hover:scale-110">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z"/></svg>
</div>
<div class="absolute inset-0 bg-slate-900/0 transition duration-300 group-hover:bg-slate-900/40"></div>
<div class="absolute inset-x-0 bottom-0 translate-y-full p-4 transition duration-300 group-hover:translate-y-0">
<p class="text-sm font-medium text-white">Mountain Sunrise</p>
</div>
</a>
<a href="#" class="group relative aspect-square overflow-hidden rounded-xl bg-[var(--ws-color-surface-alt)]">
<div class="flex h-full w-full items-center justify-center transition duration-300 group-hover:scale-110">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z"/></svg>
</div>
<div class="absolute inset-0 bg-slate-900/0 transition duration-300 group-hover:bg-slate-900/40"></div>
<div class="absolute inset-x-0 bottom-0 translate-y-full p-4 transition duration-300 group-hover:translate-y-0">
<p class="text-sm font-medium text-white">Ocean Waves</p>
</div>
</a>
<a href="#" class="group relative aspect-square overflow-hidden rounded-xl bg-[var(--ws-color-surface-alt)]">
<div class="flex h-full w-full items-center justify-center transition duration-300 group-hover:scale-110">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z"/></svg>
</div>
<div class="absolute inset-0 bg-slate-900/0 transition duration-300 group-hover:bg-slate-900/40"></div>
<div class="absolute inset-x-0 bottom-0 translate-y-full p-4 transition duration-300 group-hover:translate-y-0">
<p class="text-sm font-medium text-white">Forest Trail</p>
</div>
</a>
<a href="#" class="group relative aspect-square overflow-hidden rounded-xl bg-[var(--ws-color-surface-alt)]">
<div class="flex h-full w-full items-center justify-center transition duration-300 group-hover:scale-110">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z"/></svg>
</div>
<div class="absolute inset-0 bg-slate-900/0 transition duration-300 group-hover:bg-slate-900/40"></div>
<div class="absolute inset-x-0 bottom-0 translate-y-full p-4 transition duration-300 group-hover:translate-y-0">
<p class="text-sm font-medium text-white">City Skyline</p>
</div>
</a>
<a href="#" class="group relative aspect-square overflow-hidden rounded-xl bg-[var(--ws-color-surface-alt)]">
<div class="flex h-full w-full items-center justify-center transition duration-300 group-hover:scale-110">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z"/></svg>
</div>
<div class="absolute inset-0 bg-slate-900/0 transition duration-300 group-hover:bg-slate-900/40"></div>
<div class="absolute inset-x-0 bottom-0 translate-y-full p-4 transition duration-300 group-hover:translate-y-0">
<p class="text-sm font-medium text-white">Desert Dunes</p>
</div>
</a>
<a href="#" class="group relative aspect-square overflow-hidden rounded-xl bg-[var(--ws-color-surface-alt)]">
<div class="flex h-full w-full items-center justify-center transition duration-300 group-hover:scale-110">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z"/></svg>
</div>
<div class="absolute inset-0 bg-slate-900/0 transition duration-300 group-hover:bg-slate-900/40"></div>
<div class="absolute inset-x-0 bottom-0 translate-y-full p-4 transition duration-300 group-hover:translate-y-0">
<p class="text-sm font-medium text-white">Autumn Leaves</p>
</div>
</a>
<a href="#" class="group relative aspect-square overflow-hidden rounded-xl bg-[var(--ws-color-surface-alt)]">
<div class="flex h-full w-full items-center justify-center transition duration-300 group-hover:scale-110">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z"/></svg>
</div>
<div class="absolute inset-0 bg-slate-900/0 transition duration-300 group-hover:bg-slate-900/40"></div>
<div class="absolute inset-x-0 bottom-0 translate-y-full p-4 transition duration-300 group-hover:translate-y-0">
<p class="text-sm font-medium text-white">Snowy Peaks</p>
</div>
</a>
<a href="#" class="group relative aspect-square overflow-hidden rounded-xl bg-[var(--ws-color-surface-alt)]">
<div class="flex h-full w-full items-center justify-center transition duration-300 group-hover:scale-110">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z"/></svg>
</div>
<div class="absolute inset-0 bg-slate-900/0 transition duration-300 group-hover:bg-slate-900/40"></div>
<div class="absolute inset-x-0 bottom-0 translate-y-full p-4 transition duration-300 group-hover:translate-y-0">
<p class="text-sm font-medium text-white">Wildflower Field</p>
</div>
</a>
<a href="#" class="group relative aspect-square overflow-hidden rounded-xl bg-[var(--ws-color-surface-alt)]">
<div class="flex h-full w-full items-center justify-center transition duration-300 group-hover:scale-110">
<svg class="h-12 w-12 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z"/></svg>
</div>
<div class="absolute inset-0 bg-slate-900/0 transition duration-300 group-hover:bg-slate-900/40"></div>
<div class="absolute inset-x-0 bottom-0 translate-y-full p-4 transition duration-300 group-hover:translate-y-0">
<p class="text-sm font-medium text-white">Lakeside Sunset</p>
</div>
</a>
</div>
</div>
</section>
Details
Responsive Dark Mode Tailwind Only SSR Safe Copy & Paste
Stable Published
galleryphotosgridportfolioimagesuniform
Slots
| Name | Required | Description |
|---|---|---|
| heading | No | Section title and subtitle. |
| items | Yes | Gallery items with image placeholder, title overlay on hover. |
Uniform 3-column photo grid with 9 equal-sized items. Each item shows a camera icon placeholder, with a zoom-on-hover effect and a slide-up overlay revealing the title. Responsive: 3 → 2 → 1 columns. Dark mode supported. Pure CSS transitions.