Gallery Components
Beautiful, responsive gallery components built with TailwindCSS. Perfect for image grids, portfolios, and media showcases. Copy, paste, and customize for React, Vue, or HTML.
1. Simple Responsive Gallery
A clean, responsive image gallery with hover effects and lightbox-ready markup.
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80" alt="Gallery image 1" class="w-full h-40 object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Gallery image 2" class="w-full h-40 object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80" alt="Gallery image 3" class="w-full h-40 object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80" alt="Gallery image 4" class="w-full h-40 object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80" alt="Gallery image 5" class="w-full h-40 object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Gallery image 6" class="w-full h-40 object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80" alt="Gallery image 7" class="w-full h-40 object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80" alt="Gallery image 8" class="w-full h-40 object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
</div>
<template>
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
<div v-for="(img, i) in images" :key="i" class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img :src="img" :alt="`Gallery image ${i+1}`" class="w-full h-40 object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
</div>
</template>
<script setup>
const images = [
'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80'
]
</script>
import React from 'react'
const images = [
'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80',
'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80'
]
export default function GalleryGrid() {
return (
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
{images.map((img, i) => (
<div key={i} className="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src={img} alt={`Gallery image ${i+1}`} className="w-full h-40 object-cover group-hover:scale-105 transition-transform duration-300" />
<div className="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
))}
</div>
)
}
2. Masonry Gallery
Pinterest-style masonry layout with dynamic heights and hover effects, perfect for portfolios and creative galleries.
Image 1
Image 2
Image 3
Image 4
Image 5
Image 6
Image 7
Image 8
Image 9
Image 10
Image 11
Image 12
<div class="columns-1 md:columns-2 lg:columns-3 xl:columns-4 gap-4 space-y-4">
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80" alt="Gallery image 1" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 200px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 1</p>
</div>
</div>
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Gallery image 2" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 300px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 2</p>
</div>
</div>
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80" alt="Gallery image 3" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 250px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 3</p>
</div>
</div>
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80" alt="Gallery image 4" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 350px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 4</p>
</div>
</div>
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80" alt="Gallery image 5" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 280px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 5</p>
</div>
</div>
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Gallery image 6" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 320px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 6</p>
</div>
</div>
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80" alt="Gallery image 7" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 260px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 7</p>
</div>
</div>
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80" alt="Gallery image 8" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 380px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 8</p>
</div>
</div>
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80" alt="Gallery image 9" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 240px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 9</p>
</div>
</div>
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80" alt="Gallery image 10" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 290px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 10</p>
</div>
</div>
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Gallery image 11" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 310px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 11</p>
</div>
</div>
<div class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80" alt="Gallery image 12" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" style="height: 270px;">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image 12</p>
</div>
</div>
</div>
<template>
<div class="columns-1 md:columns-2 lg:columns-3 xl:columns-4 gap-4 space-y-4">
<div v-for="(image, i) in images" :key="i" class="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img :src="image.src" :alt="`Gallery image ${i+1}`" class="w-full object-cover group-hover:scale-105 transition-transform duration-300" :style="{ height: image.height + 'px' }">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p class="text-white text-sm font-medium">Image {{ i+1 }}</p>
</div>
</div>
</div>
</template>
<script setup>
const images = [
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80', height: 200 },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80', height: 300 },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80', height: 250 },
{ src: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80', height: 350 },
{ src: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80', height: 280 },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80', height: 320 },
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80', height: 260 },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80', height: 380 },
{ src: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80', height: 240 },
{ src: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80', height: 290 },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80', height: 310 },
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80', height: 270 }
]
</script>
import React from 'react'
const images = [
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80', height: 200 },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80', height: 300 },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80', height: 250 },
{ src: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80', height: 350 },
{ src: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80', height: 280 },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80', height: 320 },
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80', height: 260 },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80', height: 380 },
{ src: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80', height: 240 },
{ src: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80', height: 290 },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80', height: 310 },
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80', height: 270 }
]
export default function MasonryGallery() {
return (
<div className="columns-1 md:columns-2 lg:columns-3 xl:columns-4 gap-4 space-y-4">
{images.map((galleryImage, i) => (
<div key={i} className="break-inside-avoid group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src={} alt={`Gallery image ${i+1}`} className="w-full object-cover group-hover:scale-105 transition-transform duration-300" />
<div className="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity">
<p className="text-white text-sm font-medium">Image {i+1}</p>
</div>
</div>
))}
</div>
)
}
3. Lightbox Gallery
Responsive image grid with click-to-open lightbox functionality, navigation controls, and keyboard support.
<!-- AlpineJS Lightbox Gallery (HTML + Tailwind) -->
<div x-data="{ lightboxOpen: false, currentImage: 0, images: [
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=600&q=80', alt: 'Mountain landscape', full: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=600&q=80', alt: 'Forest path', full: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=600&q=80', alt: 'Ocean waves', full: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=600&q=80', alt: 'City skyline', full: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=600&q=80', alt: 'Desert sunset', full: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=600&q=80', alt: 'Forest path', full: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=600&q=80', alt: 'Mountain landscape', full: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=600&q=80', alt: 'Ocean waves', full: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=1200&q=80' }
] }" @keydown.escape.window="lightboxOpen = false" @keydown.arrow-left.window="if(lightboxOpen) prevImage()" @keydown.arrow-right.window="if(lightboxOpen) nextImage()">
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
<template x-for="(image, i) in images" :key="i">
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all cursor-pointer" @click="currentImage = i; lightboxOpen = true">
<img :src="image.src" :alt="image.alt" class="w-full h-48 object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
</div>
</div>
</template>
</div>
<!-- Lightbox -->
<div x-show="lightboxOpen" x-cloak class="fixed inset-0 z-50 flex items-center justify-center bg-black/90" @click="lightboxOpen = false">
<div class="relative max-w-4xl max-h-screen p-4" @click.stop>
<img :src="images[currentImage].full" :alt="images[currentImage].alt" class="max-w-full max-h-full object-contain">
<button @click="lightboxOpen = false" class="absolute top-2 right-2 text-white hover:text-gray-300">
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
<button @click="prevImage()" class="absolute left-2 top-1/2 -translate-y-1/2 text-white hover:text-gray-300">
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
</svg>
</button>
<button @click="nextImage()" class="absolute right-2 top-1/2 -translate-y-1/2 text-white hover:text-gray-300">
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
</button>
<div class="absolute bottom-2 left-1/2 -translate-x-1/2 text-white">
<span x-text="(currentImage + 1) + ' / ' + images.length"></span>
</div>
</div>
</div>
</div>
<!-- Alpine.js helper functions (include once) -->
<script>
function prevImage() {
this.currentImage = (this.currentImage - 1 + this.images.length) % this.images.length;
}
function nextImage() {
this.currentImage = (this.currentImage + 1) % this.images.length;
}
</script>
<template>
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
<div v-for="(image, i) in images" :key="i" class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all cursor-pointer" @click="openLightbox(i)">
<img :src="image.src" :alt="image.alt" class="w-full h-48 object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
</div>
</div>
</div>
<!-- Lightbox -->
<div v-if="lightboxOpen" class="fixed inset-0 z-50 flex items-center justify-center bg-black/90" @click="closeLightbox">
<div class="relative max-w-4xl max-h-screen p-4" @click.stop>
<img :src="images[currentImage].full" :alt="images[currentImage].alt" class="max-w-full max-h-full object-contain">
<button @click="closeLightbox" class="absolute top-2 right-2 text-white hover:text-gray-300">
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
<button @click="prevImage" class="absolute left-2 top-1/2 -translate-y-1/2 text-white hover:text-gray-300">
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
</svg>
</button>
<button @click="nextImage" class="absolute right-2 top-1/2 -translate-y-1/2 text-white hover:text-gray-300">
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
</button>
<div class="absolute bottom-2 left-1/2 -translate-x-1/2 text-white">
{{ currentImage + 1 }} / {{ images.length }}
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const lightboxOpen = ref(false)
const currentImage = ref(0)
const images = ref([
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=600&q=80', alt: 'Mountain landscape', full: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=600&q=80', alt: 'Forest path', full: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=600&q=80', alt: 'Ocean waves', full: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=600&q=80', alt: 'City skyline', full: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=600&q=80', alt: 'Desert sunset', full: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=600&q=80', alt: 'Forest path', full: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=600&q=80', alt: 'Mountain landscape', full: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=600&q=80', alt: 'Ocean waves', full: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=1200&q=80' }
])
const openLightbox = (index) => {
currentImage.value = index
lightboxOpen.value = true
}
const closeLightbox = () => {
lightboxOpen.value = false
}
const nextImage = () => {
currentImage.value = (currentImage.value + 1) % images.value.length
}
const prevImage = () => {
currentImage.value = (currentImage.value - 1 + images.value.length) % images.value.length
}
</script>
import React, { useState } from 'react'
const images = [
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=600&q=80', alt: 'Mountain landscape', full: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=600&q=80', alt: 'Forest path', full: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=600&q=80', alt: 'Ocean waves', full: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=600&q=80', alt: 'City skyline', full: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=600&q=80', alt: 'Desert sunset', full: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=600&q=80', alt: 'Forest path', full: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=600&q=80', alt: 'Mountain landscape', full: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=1200&q=80' },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=600&q=80', alt: 'Ocean waves', full: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=1200&q=80' }
]
export default function LightboxGallery() {
const [lightboxOpen, setLightboxOpen] = useState(false)
const [currentImage, setCurrentImage] = useState(0)
const openLightbox = (index) => {
setCurrentImage(index)
setLightboxOpen(true)
}
const closeLightbox = () => {
setLightboxOpen(false)
}
const nextImage = () => {
setCurrentImage((prev) => (prev + 1) % images.length)
}
const prevImage = () => {
setCurrentImage((prev) => (prev - 1 + images.length) % images.length)
}
return (
<>
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
{images.map((image, i) => (
<div key={i} className="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all cursor-pointer" onClick={() => openLightbox(i)}>
<img src={image.src} alt={image.alt} className="w-full h-48 object-cover group-hover:scale-105 transition-transform duration-300" />
<div className="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</div>
</div>
))}
</div>
{lightboxOpen && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/90" onClick={closeLightbox}>
<div className="relative max-w-4xl max-h-screen p-4" onClick={(e) => e.stopPropagation()}>
<img src={images[currentImage].full} alt={images[currentImage].alt} className="max-w-full max-h-full object-contain" />
<button onClick={closeLightbox} className="absolute top-2 right-2 text-white hover:text-gray-300">
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<button onClick={prevImage} className="absolute left-2 top-1/2 -translate-y-1/2 text-white hover:text-gray-300">
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 19l-7-7 7-7" />
</svg>
</button>
<button onClick={nextImage} className="absolute right-2 top-1/2 -translate-y-1/2 text-white hover:text-gray-300">
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 5l7 7-7 7" />
</svg>
</button>
<div className="absolute bottom-2 left-1/2 -translate-x-1/2 text-white">
{currentImage + 1} / {images.length}
</div>
</div>
</div>
)}
</>
)
}
4. Advanced Grid Gallery
Complex CSS Grid layout with varying image sizes, perfect for showcasing featured content with supporting images.
Featured
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 auto-rows-[200px]">
<!-- Featured Image - spans 2 columns -->
<div class="md:col-span-2 lg:col-span-2 xl:col-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=800&q=80" alt="Featured landscape" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-4 left-4 text-white">
<p class="text-lg font-semibold">Featured</p>
</div>
</div>
<!-- Regular images -->
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Forest path" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80" alt="Ocean waves" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Wide image - spans 2 columns -->
<div class="md:col-span-2 lg:col-span-2 xl:col-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=800&q=80" alt="City skyline" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Tall image - spans 2 rows -->
<div class="md:row-span-2 lg:row-span-2 xl:row-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80" alt="Desert sunset" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Regular images -->
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Forest path" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80" alt="Mountain landscape" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80" alt="Ocean waves" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Wide image - spans 2 columns -->
<div class="md:col-span-2 lg:col-span-2 xl:col-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=800&q=80" alt="City skyline" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
</div>
<template>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 auto-rows-[200px]">
<!-- Featured Image - spans 2 columns -->
<div class="md:col-span-2 lg:col-span-2 xl:col-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=800&q=80" alt="Featured landscape" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="absolute bottom-4 left-4 text-white">
<p class="text-lg font-semibold">Featured</p>
</div>
</div>
<!-- Regular images -->
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Forest path" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80" alt="Ocean waves" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Wide image - spans 2 columns -->
<div class="md:col-span-2 lg:col-span-2 xl:col-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=800&q=80" alt="City skyline" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Tall image - spans 2 rows -->
<div class="md:row-span-2 lg:row-span-2 xl:row-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80" alt="Desert sunset" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Regular images -->
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Forest path" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80" alt="Mountain landscape" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80" alt="Ocean waves" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Wide image - spans 2 columns -->
<div class="md:col-span-2 lg:col-span-2 xl:col-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=800&q=80" alt="City skyline" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
</div>
</template>
<script setup>
</script>
import React from 'react'
export default function AdvancedGridGallery() {
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 auto-rows-[200px]">
<!-- Featured Image - spans 2 columns -->
<div className="md:col-span-2 lg:col-span-2 xl:col-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=800&q=80" alt="Featured landscape" className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
<div className="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div className="absolute bottom-4 left-4 text-white">
<p className="text-lg font-semibold">Featured</p>
</div>
</div>
<!-- Regular images -->
<div className="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Forest path" className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div className="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80" alt="Ocean waves" className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Wide image - spans 2 columns -->
<div class="md:col-span-2 lg:col-span-2 xl:col-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=800&q=80" alt="City skyline" className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Tall image - spans 2 rows -->
<div className="md:row-span-2 lg:row-span-2 xl:row-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80" alt="Desert sunset" className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Regular images -->
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Forest path" className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80" alt="Mountain landscape" className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div class="group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80" alt="Ocean waves" className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<!-- Wide image - spans 2 columns -->
<div class="md:col-span-2 lg:col-span-2 xl:col-span-2 group relative overflow-hidden rounded-xl border border-black/10 shadow hover:shadow-lg transition-all">
<img src="https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=800&q=80" alt="City skyline" className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
<div class="absolute inset-0 bg-black/10 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
</div>
)
}
6. Neobrutalist Gallery
Bold neobrutalist design with thick borders, vibrant colors, and overlay text on hover - perfect for creative portfolios and modern galleries.
Mountain View
Stunning landscape photography
Forest Path
Serene nature photography
Ocean Waves
Dynamic seascape photography
City Skyline
Urban architecture photography
Desert Sunset
Golden hour landscape
Forest Path
Woodland adventure photography
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="group relative overflow-hidden bg-white border-4 border-black shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] hover:shadow-[12px_12px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[-2px] hover:translate-y-[-2px] transition-all duration-200">
<div class="aspect-square bg-[#ffde59] overflow-hidden">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80" alt="Mountain landscape" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-300">
</div>
<div class="absolute inset-0 bg-black/80 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<div class="text-center text-white p-4">
<h3 class="text-xl font-black mb-2">Mountain View</h3>
<p class="text-sm font-bold opacity-90">Stunning landscape photography</p>
</div>
</div>
</div>
<div class="group relative overflow-hidden bg-white border-4 border-black shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] hover:shadow-[12px_12px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[-2px] hover:translate-y-[-2px] transition-all duration-200">
<div class="aspect-square bg-[#ff5c5c] overflow-hidden">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Forest path" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-300">
</div>
<div class="absolute inset-0 bg-black/80 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<div class="text-center text-white p-4">
<h3 class="text-xl font-black mb-2">Forest Path</h3>
<p class="text-sm font-bold opacity-90">Serene nature photography</p>
</div>
</div>
</div>
<div class="group relative overflow-hidden bg-white border-4 border-black shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] hover:shadow-[12px_12px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[-2px] hover:translate-y-[-2px] transition-all duration-200">
<div class="aspect-square bg-violet overflow-hidden">
<img src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80" alt="Ocean waves" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-300">
</div>
<div class="absolute inset-0 bg-black/80 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<div class="text-center text-white p-4">
<h3 class="text-xl font-black mb-2">Ocean Waves</h3>
<p class="text-sm font-bold opacity-90">Dynamic seascape photography</p>
</div>
</div>
</div>
<div class="group relative overflow-hidden bg-white border-4 border-black shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] hover:shadow-[12px_12px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[-2px] hover:translate-y-[-2px] transition-all duration-200">
<div class="aspect-square bg-[#ffde59] overflow-hidden">
<img src="https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80" alt="City skyline" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-300">
</div>
<div class="absolute inset-0 bg-black/80 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<div class="text-center text-white p-4">
<h3 class="text-xl font-black mb-2">City Skyline</h3>
<p class="text-sm font-bold opacity-90">Urban architecture photography</p>
</div>
</div>
</div>
<div class="group relative overflow-hidden bg-white border-4 border-black shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] hover:shadow-[12px_12px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[-2px] hover:translate-y-[-2px] transition-all duration-200">
<div class="aspect-square bg-[#ff5c5c] overflow-hidden">
<img src="https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80" alt="Desert sunset" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-300">
</div>
<div class="absolute inset-0 bg-black/80 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<div class="text-center text-white p-4">
<h3 class="text-xl font-black mb-2">Desert Sunset</h3>
<p class="text-sm font-bold opacity-90">Golden hour landscape</p>
</div>
</div>
</div>
<div class="group relative overflow-hidden bg-white border-4 border-black shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] hover:shadow-[12px_12px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[-2px] hover:translate-y-[-2px] transition-all duration-200">
<div class="aspect-square bg-violet overflow-hidden">
<img src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80" alt="Forest path" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-300">
</div>
<div class="absolute inset-0 bg-black/80 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<div class="text-center text-white p-4">
<h3 class="text-xl font-black mb-2">Forest Path</h3>
<p class="text-sm font-bold opacity-90">Woodland adventure photography</p>
</div>
</div>
</div>
</div>
<template>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div v-for="(image, i) in images" :key="i" class="group relative overflow-hidden bg-white border-4 border-black shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] hover:shadow-[12px_12px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[-2px] hover:translate-y-[-2px] transition-all duration-200">
<div :class="image.bgColor" class="aspect-square overflow-hidden">
<img :src="image.src" :alt="image.alt" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-300">
</div>
<div class="absolute inset-0 bg-black/80 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<div class="text-center text-white p-4">
<h3 class="text-xl font-black mb-2">{{ image.title }}</h3>
<p class="text-sm font-bold opacity-90">{{ image.description }}</p>
</div>
</div>
</div>
</div>
</template>
<script setup>
const images = [
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80', alt: 'Mountain landscape', bgColor: 'bg-[#ffde59]', title: 'Mountain View', description: 'Stunning landscape photography' },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80', alt: 'Forest path', bgColor: 'bg-[#ff5c5c]', title: 'Forest Path', description: 'Serene nature photography' },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80', alt: 'Ocean waves', bgColor: 'bg-violet', title: 'Ocean Waves', description: 'Dynamic seascape photography' },
{ src: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80', alt: 'City skyline', bgColor: 'bg-[#ffde59]', title: 'City Skyline', description: 'Urban architecture photography' },
{ src: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80', alt: 'Desert sunset', bgColor: 'bg-[#ff5c5c]', title: 'Desert Sunset', description: 'Golden hour landscape' },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80', alt: 'Forest path', bgColor: 'bg-violet', title: 'Forest Path', description: 'Woodland adventure photography' }
]
</script>
import React from 'react'
const images = [
{ src: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80', alt: 'Mountain landscape', bgColor: 'bg-[#ffde59]', title: 'Mountain View', description: 'Stunning landscape photography' },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80', alt: 'Forest path', bgColor: 'bg-[#ff5c5c]', title: 'Forest Path', description: 'Serene nature photography' },
{ src: 'https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80', alt: 'Ocean waves', bgColor: 'bg-violet', title: 'Ocean Waves', description: 'Dynamic seascape photography' },
{ src: 'https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80', alt: 'City skyline', bgColor: 'bg-[#ffde59]', title: 'City Skyline', description: 'Urban architecture photography' },
{ src: 'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80', alt: 'Desert sunset', bgColor: 'bg-[#ff5c5c]', title: 'Desert Sunset', description: 'Golden hour landscape' },
{ src: 'https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80', alt: 'Forest path', bgColor: 'bg-violet', title: 'Forest Path', description: 'Woodland adventure photography' }
]
export default function NeobrutalistGallery() {
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{images.map((image, i) => (
<div key={i} className="group relative overflow-hidden bg-white border-4 border-black shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] hover:shadow-[12px_12px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[-2px] hover:translate-y-[-2px] transition-all duration-200">
<div className={`aspect-square overflow-hidden ${image.bgColor}`}>
<img src={image.src} alt={image.alt} className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-300" />
</div>
<div className="absolute inset-0 bg-black/80 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<div className="text-center text-white p-4">
<h3 className="text-xl font-black mb-2">{image.title}</h3>
<p className="text-sm font-bold opacity-90">{image.description}</p>
</div>
</div>
</div>
))}
</div>
)
}