<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background: #f8f9fa;
padding: 60px 0;
}
.gallery-header {
text-align: center;
margin-bottom: 50px;
}
.gallery-header h1 {
font-size: 2.5rem;
font-weight: 700;
color: #2c3e50;
margin-bottom: 15px;
}
.gallery-header p {
color: #7f8c8d;
font-size: 1.1rem;
}
/* Filter Buttons */
.filter-container {
text-align: center;
margin-bottom: 40px;
}
.filter-btn {
background: white;
border: 2px solid #e0e0e0;
color: #555;
padding: 10px 25px;
margin: 5px;
border-radius: 50px;
font-weight: 600;
transition: all 0.3s ease;
cursor: pointer;
}
.filter-btn:hover {
background: #667eea;
color: white;
border-color: #667eea;
transform: translateY(-2px);
}
.filter-btn.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-color: transparent;
}
/* Masonry Grid */
.masonry-grid {
column-count: 4;
column-gap: 20px;
}
@media (max-width: 1200px) {
.masonry-grid {
column-count: 3;
}
}
@media (max-width: 768px) {
.masonry-grid {
column-count: 2;
}
}
@media (max-width: 576px) {
.masonry-grid {
column-count: 1;
}
}
/* Gallery Item */
.gallery-item {
break-inside: avoid;
margin-bottom: 20px;
transition: all 0.3s ease;
opacity: 1;
}
.gallery-item.hide {
display: none;
}
.gallery-card {
position: relative;
overflow: hidden;
border-radius: 15px;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
transition: all 0.3s ease;
background: white;
cursor: pointer;
}
.gallery-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0,0,0,0.2);
}
.gallery-image {
width: 100%;
display: block;
transition: transform 0.5s ease;
}
.gallery-card:hover .gallery-image {
transform: scale(1.1);
}
.gallery-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to bottom, transparent 0%, rgba(0,0,0,0.8) 100%);
opacity: 0;
transition: opacity 0.3s ease;
display: flex;
flex-direction: column;
justify-content: flex-end;
padding: 20px;
}
.gallery-card:hover .gallery-overlay {
opacity: 1;
}
.gallery-title {
color: white;
font-size: 1.1rem;
font-weight: 700;
margin-bottom: 5px;
transform: translateY(20px);
transition: transform 0.3s ease 0.1s;
}
.gallery-card:hover .gallery-title {
transform: translateY(0);
}
.gallery-category {
color: white;
font-size: 0.85rem;
opacity: 0.9;
transform: translateY(20px);
transition: transform 0.3s ease 0.15s;
}
.gallery-card:hover .gallery-category {
transform: translateY(0);
}
/* Lightbox Modal */
.lightbox-modal {
display: none;
position: fixed;
z-index: 9999;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.95);
align-items: center;
justify-content: center;
}
.lightbox-modal.active {
display: flex;
animation: fadeIn 0.3s ease;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.lightbox-content {
max-width: 90%;
max-height: 90%;
position: relative;
}
.lightbox-image {
max-width: 100%;
max-height: 90vh;
border-radius: 10px;
box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}
.lightbox-close {
position: absolute;
top: -40px;
right: 0;
background: white;
color: #2c3e50;
width: 40px;
height: 40px;
border-radius: 50%;
border: none;
font-size: 1.5rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
.lightbox-close:hover {
background: #667eea;
color: white;
transform: rotate(90deg);
}
.lightbox-info {
background: white;
padding: 20px;
border-radius: 10px;
margin-top: 20px;
text-align: center;
}
.lightbox-info h3 {
font-size: 1.5rem;
font-weight: 700;
color: #2c3e50;
margin-bottom: 5px;
}
.lightbox-info p {
color: #7f8c8d;
margin: 0;
}
/* Loading Animation */
.loading {
text-align: center;
padding: 40px;
}
.loading-spinner {
border: 4px solid #f3f3f3;
border-top: 4px solid #667eea;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<div class="container">
<!-- Header -->
<div class="gallery-header">
<h1>Masonry Gallery</h1>
<p>Beautiful responsive image gallery with masonry layout</p>
</div>
<!-- Filter Buttons -->
<div class="filter-container">
<button class="filter-btn active" data-filter="all">All</button>
<button class="filter-btn" data-filter="nature">Nature</button>
<button class="filter-btn" data-filter="architecture">Architecture</button>
<button class="filter-btn" data-filter="people">People</button>
<button class="filter-btn" data-filter="food">Food</button>
<button class="filter-btn" data-filter="travel">Travel</button>
</div>
<!-- Masonry Gallery -->
<div class="masonry-grid" id="gallery">
<!-- Nature Images -->
<div class="gallery-item" data-category="nature">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Mountain Landscape" data-category="Nature">
<div style="height: 300px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Mountain Landscape</div>
<div class="gallery-category">Nature</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="architecture">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Modern Building" data-category="Architecture">
<div style="height: 400px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Modern Building</div>
<div class="gallery-category">Architecture</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="nature">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Forest Path" data-category="Nature">
<div style="height: 350px; background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Forest Path</div>
<div class="gallery-category">Nature</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="people">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Portrait Photography" data-category="People">
<div style="height: 280px; background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Portrait Photography</div>
<div class="gallery-category">People</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="food">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Gourmet Dish" data-category="Food">
<div style="height: 320px; background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Gourmet Dish</div>
<div class="gallery-category">Food</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="architecture">
<div class="gallery-card" onclick="openLightbox(this)" data-title="City Skyline" data-category="Architecture">
<div style="height: 360px; background: linear-gradient(135deg, #30cfd0 0%, #330867 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">City Skyline</div>
<div class="gallery-category">Architecture</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="travel">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Beach Sunset" data-category="Travel">
<div style="height: 290px; background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Beach Sunset</div>
<div class="gallery-category">Travel</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="nature">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Waterfall" data-category="Nature">
<div style="height: 380px; background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Waterfall</div>
<div class="gallery-category">Nature</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="food">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Fresh Salad" data-category="Food">
<div style="height: 310px; background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Fresh Salad</div>
<div class="gallery-category">Food</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="people">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Street Photography" data-category="People">
<div style="height: 340px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Street Photography</div>
<div class="gallery-category">People</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="travel">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Ancient Temple" data-category="Travel">
<div style="height: 370px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Ancient Temple</div>
<div class="gallery-category">Travel</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="architecture">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Glass Building" data-category="Architecture">
<div style="height: 330px; background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Glass Building</div>
<div class="gallery-category">Architecture</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="nature">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Flower Garden" data-category="Nature">
<div style="height: 295px; background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Flower Garden</div>
<div class="gallery-category">Nature</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="food">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Dessert Platter" data-category="Food">
<div style="height: 355px; background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Dessert Platter</div>
<div class="gallery-category">Food</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="travel">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Mountain Road" data-category="Travel">
<div style="height: 315px; background: linear-gradient(135deg, #30cfd0 0%, #330867 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Mountain Road</div>
<div class="gallery-category">Travel</div>
</div>
</div>
</div>
<div class="gallery-item" data-category="people">
<div class="gallery-card" onclick="openLightbox(this)" data-title="Group Photo" data-category="People">
<div style="height: 345px; background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);" class="gallery-image"></div>
<div class="gallery-overlay">
<div class="gallery-title">Group Photo</div>
<div class="gallery-category">People</div>
</div>
</div>
</div>
</div>
</div>
<!-- Lightbox Modal -->
<div class="lightbox-modal" id="lightbox" onclick="closeLightbox(event)">
<div class="lightbox-content">
<button class="lightbox-close" onclick="closeLightbox(event)">×</button>
<div id="lightboxImageContainer"></div>
<div class="lightbox-info">
<h3 id="lightboxTitle"></h3>
<p id="lightboxCategory"></p>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
<script>
// Filter functionality
const filterButtons = document.querySelectorAll('.filter-btn');
const galleryItems = document.querySelectorAll('.gallery-item');
filterButtons.forEach(button => {
button.addEventListener('click', () => {
// Remove active class from all buttons
filterButtons.forEach(btn => btn.classList.remove('active'));
// Add active class to clicked button
button.classList.add('active');
const filterValue = button.getAttribute('data-filter');
galleryItems.forEach(item => {
if (filterValue === 'all') {
item.classList.remove('hide');
} else {
if (item.getAttribute('data-category') === filterValue) {
item.classList.remove('hide');
} else {
item.classList.add('hide');
}
}
});
});
});
// Lightbox functionality
function openLightbox(element) {
const lightbox = document.getElementById('lightbox');
const title = element.getAttribute('data-title');
const category = element.getAttribute('data-category');
const imageElement = element.querySelector('.gallery-image');
// Clone the image
const clonedImage = imageElement.cloneNode(true);
clonedImage.classList.add('lightbox-image');
clonedImage.style.height = 'auto';
// Set content
document.getElementById('lightboxImageContainer').innerHTML = '';
document.getElementById('lightboxImageContainer').appendChild(clonedImage);
document.getElementById('lightboxTitle').textContent = title;
document.getElementById('lightboxCategory').textContent = category;
// Show lightbox
lightbox.classList.add('active');
document.body.style.overflow = 'hidden';
}
function closeLightbox(event) {
if (event.target.id === 'lightbox' || event.target.classList.contains('lightbox-close')) {
const lightbox = document.getElementById('lightbox');
lightbox.classList.remove('active');
document.body.style.overflow = 'auto';
}
}
// Close lightbox with ESC key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
const lightbox = document.getElementById('lightbox');
if (lightbox.classList.contains('active')) {
lightbox.classList.remove('active');
document.body.style.overflow = 'auto';
}
}
});
</script>
Login to leave a comment
Login
No comments yet. Be the first!