🖼️ Project: Image Gallery

Responsive Photo Gallery

Image Gallery Project

Create a beautiful, responsive image gallery with lightbox functionality and filtering options.

📋 Project Overview

  • Objective: Build an interactive photo gallery
  • Features: Grid layout, categories, lightbox, responsive
  • Sections: Filter buttons, gallery grid, modal viewer
  • Focus: Visual appeal and user interaction

💻 Complete Gallery HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Photo Gallery</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f8f9fa;
            color: #333;
        }
        
        /* Header */
        header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 3rem 2rem;
            text-align: center;
        }
        
        header h1 {
            font-size: 3rem;
            margin-bottom: 0.5rem;
        }
        
        header p {
            font-size: 1.2rem;
            opacity: 0.9;
        }
        
        /* Filter Buttons */
        .filter-container {
            max-width: 1200px;
            margin: 2rem auto;
            padding: 0 2rem;
            text-align: center;
        }
        
        .filter-buttons {
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
            gap: 1rem;
            margin-bottom: 2rem;
        }
        
        .filter-btn {
            padding: 0.8rem 2rem;
            background: white;
            border: 2px solid #ecf0f1;
            border-radius: 25px;
            cursor: pointer;
            font-size: 1rem;
            font-weight: 500;
            transition: all 0.3s;
        }
        
        .filter-btn:hover {
            border-color: #667eea;
            color: #667eea;
        }
        
        .filter-btn.active {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border-color: transparent;
        }
        
        /* Gallery Grid */
        .gallery {
            max-width: 1200px;
            margin: 0 auto;
            padding: 0 2rem 3rem;
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
            gap: 1.5rem;
        }
        
        .gallery-item {
            position: relative;
            overflow: hidden;
            border-radius: 10px;
            cursor: pointer;
            aspect-ratio: 1;
            background: #ecf0f1;
        }
        
        .gallery-item img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: transform 0.3s;
        }
        
        .gallery-item:hover img {
            transform: scale(1.1);
        }
        
        .gallery-item-overlay {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.7);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            opacity: 0;
            transition: opacity 0.3s;
        }
        
        .gallery-item:hover .gallery-item-overlay {
            opacity: 1;
        }
        
        .gallery-item-title {
            color: white;
            font-size: 1.3rem;
            font-weight: bold;
            margin-bottom: 0.5rem;
        }
        
        .gallery-item-category {
            color: #ecf0f1;
            font-size: 0.9rem;
        }
        
        .gallery-item-icon {
            font-size: 2rem;
            color: white;
            margin-top: 1rem;
        }
        
        /* Hidden state for filtered items */
        .gallery-item.hidden {
            display: none;
        }
        
        /* Lightbox Modal */
        .lightbox {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.95);
            z-index: 1000;
            animation: fadeIn 0.3s;
        }
        
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        
        .lightbox.active {
            display: flex;
            justify-content: center;
            align-items: center;
        }
        
        .lightbox-content {
            max-width: 90%;
            max-height: 90%;
            position: relative;
        }
        
        .lightbox-image {
            max-width: 100%;
            max-height: 90vh;
            border-radius: 10px;
            box-shadow: 0 10px 50px rgba(0,0,0,0.5);
        }
        
        .lightbox-caption {
            color: white;
            text-align: center;
            margin-top: 1rem;
            font-size: 1.2rem;
        }
        
        /* Lightbox Controls */
        .lightbox-close {
            position: absolute;
            top: 20px;
            right: 30px;
            font-size: 3rem;
            color: white;
            cursor: pointer;
            transition: color 0.3s;
            z-index: 1001;
        }
        
        .lightbox-close:hover {
            color: #667eea;
        }
        
        .lightbox-prev,
        .lightbox-next {
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            font-size: 3rem;
            color: white;
            cursor: pointer;
            padding: 1rem;
            transition: color 0.3s;
            user-select: none;
        }
        
        .lightbox-prev {
            left: 20px;
        }
        
        .lightbox-next {
            right: 20px;
        }
        
        .lightbox-prev:hover,
        .lightbox-next:hover {
            color: #667eea;
        }
        
        /* Image Counter */
        .lightbox-counter {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            color: white;
            background: rgba(0,0,0,0.5);
            padding: 0.5rem 1.5rem;
            border-radius: 20px;
            font-size: 0.9rem;
        }
        
        /* Search Box */
        .search-container {
            max-width: 600px;
            margin: 2rem auto;
            padding: 0 2rem;
        }
        
        .search-box {
            width: 100%;
            padding: 1rem;
            border: 2px solid #ecf0f1;
            border-radius: 25px;
            font-size: 1rem;
            transition: border-color 0.3s;
        }
        
        .search-box:focus {
            outline: none;
            border-color: #667eea;
        }
        
        /* Stats Section */
        .stats {
            max-width: 1200px;
            margin: 3rem auto 2rem;
            padding: 0 2rem;
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 1.5rem;
            text-align: center;
        }
        
        .stat-card {
            background: white;
            padding: 2rem;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.08);
        }
        
        .stat-number {
            font-size: 2.5rem;
            font-weight: bold;
            color: #667eea;
            margin-bottom: 0.5rem;
        }
        
        .stat-label {
            color: #7f8c8d;
            font-size: 0.9rem;
        }
        
        /* Footer */
        footer {
            background: #2c3e50;
            color: white;
            text-align: center;
            padding: 2rem;
            margin-top: 3rem;
        }
        
        /* Responsive */
        @media (max-width: 768px) {
            .gallery {
                grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
                gap: 1rem;
            }
            
            .lightbox-prev,
            .lightbox-next {
                font-size: 2rem;
                padding: 0.5rem;
            }
            
            .lightbox-close {
                font-size: 2rem;
                top: 10px;
                right: 10px;
            }
        }
    </style>
</head>
<body>
    <!-- Header -->
    <header>
        <h1>🖼️ Photo Gallery</h1>
        <p>A Collection of Beautiful Moments</p>
    </header>

    <!-- Search Box -->
    <div class="search-container">
        <input type="search" class="search-box" placeholder="🔍 Search images..." id="searchBox">
    </div>

    <!-- Stats Section -->
    <div class="stats">
        <div class="stat-card">
            <div class="stat-number">150+</div>
            <div class="stat-label">Total Photos</div>
        </div>
        <div class="stat-card">
            <div class="stat-number">12</div>
            <div class="stat-label">Categories</div>
        </div>
        <div class="stat-card">
            <div class="stat-number">5K+</div>
            <div class="stat-label">Downloads</div>
        </div>
        <div class="stat-card">
            <div class="stat-number">4.8⭐</div>
            <div class="stat-label">Average Rating</div>
        </div>
    </div>

    <!-- Filter Buttons -->
    <div class="filter-container">
        <div class="filter-buttons">
            <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="animals">Animals</button>
            <button class="filter-btn" data-filter="food">Food</button>
        </div>
    </div>

    <!-- Gallery Grid -->
    <div class="gallery" id="gallery">
        <!-- Nature Images -->
        <div class="gallery-item" data-category="nature" data-title="Mountain Landscape">
            <img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4" alt="Mountain Landscape">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Mountain Landscape</div>
                <div class="gallery-item-category">Nature</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <div class="gallery-item" data-category="nature" data-title="Forest Path">
            <img src="https://images.unsplash.com/photo-1441974231531-c6227db76b6e" alt="Forest Path">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Forest Path</div>
                <div class="gallery-item-category">Nature</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <div class="gallery-item" data-category="nature" data-title="Ocean Sunset">
            <img src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e" alt="Ocean Sunset">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Ocean Sunset</div>
                <div class="gallery-item-category">Nature</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <!-- Architecture Images -->
        <div class="gallery-item" data-category="architecture" data-title="Modern Building">
            <img src="https://images.unsplash.com/photo-1480714378408-67cf0d13bc1b" alt="Modern Building">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Modern Building</div>
                <div class="gallery-item-category">Architecture</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <div class="gallery-item" data-category="architecture" data-title="City Skyline">
            <img src="https://images.unsplash.com/photo-1449824913935-59a10b8d2000" alt="City Skyline">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">City Skyline</div>
                <div class="gallery-item-category">Architecture</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <div class="gallery-item" data-category="architecture" data-title="Bridge Structure">
            <img src="https://images.unsplash.com/photo-1470770903676-69b98201ea1c" alt="Bridge Structure">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Bridge Structure</div>
                <div class="gallery-item-category">Architecture</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <!-- People Images -->
        <div class="gallery-item" data-category="people" data-title="Happy People">
            <img src="https://images.unsplash.com/photo-1511632765486-a01980e01a18" alt="Happy People">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Happy People</div>
                <div class="gallery-item-category">People</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <div class="gallery-item" data-category="people" data-title="Portrait">
            <img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d" alt="Portrait">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Portrait</div>
                <div class="gallery-item-category">People</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <div class="gallery-item" data-category="people" data-title="Group Photo">
            <img src="https://images.unsplash.com/photo-1529156069898-49953e39b3ac" alt="Group Photo">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Group Photo</div>
                <div class="gallery-item-category">People</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <!-- Animals Images -->
        <div class="gallery-item" data-category="animals" data-title="Wild Tiger">
            <img src="https://images.unsplash.com/photo-1489084917528-a57e68a79a1e" alt="Wild Tiger">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Wild Tiger</div>
                <div class="gallery-item-category">Animals</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <div class="gallery-item" data-category="animals" data-title="Cute Dog">
            <img src="https://images.unsplash.com/photo-1517849845537-4d257902454a" alt="Cute Dog">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Cute Dog</div>
                <div class="gallery-item-category">Animals</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <div class="gallery-item" data-category="animals" data-title="Colorful Birds">
            <img src="https://images.unsplash.com/photo-1444464666168-49d633b86797" alt="Colorful Birds">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Colorful Birds</div>
                <div class="gallery-item-category">Animals</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <!-- Food Images -->
        <div class="gallery-item" data-category="food" data-title="Delicious Meal">
            <img src="https://images.unsplash.com/photo-1504674900247-0877df9cc836" alt="Delicious Meal">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Delicious Meal</div>
                <div class="gallery-item-category">Food</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <div class="gallery-item" data-category="food" data-title="Fresh Fruits">
            <img src="https://images.unsplash.com/photo-1490474418585-ba9bad8fd0ea" alt="Fresh Fruits">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Fresh Fruits</div>
                <div class="gallery-item-category">Food</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
        
        <div class="gallery-item" data-category="food" data-title="Gourmet Dish">
            <img src="https://images.unsplash.com/photo-1476224203421-9ac39bcb3327" alt="Gourmet Dish">
            <div class="gallery-item-overlay">
                <div class="gallery-item-title">Gourmet Dish</div>
                <div class="gallery-item-category">Food</div>
                <div class="gallery-item-icon">🔍</div>
            </div>
        </div>
    </div>

    <!-- Lightbox Modal -->
    <div class="lightbox" id="lightbox">
        <span class="lightbox-close" id="lightboxClose">×</span>
        <span class="lightbox-prev" id="lightboxPrev">❮</span>
        <span class="lightbox-next" id="lightboxNext">❯</span>
        <div class="lightbox-content">
            <img src="" alt="" class="lightbox-image" id="lightboxImage">
            <div class="lightbox-caption" id="lightboxCaption"></div>
            <div class="lightbox-counter" id="lightboxCounter"></div>
        </div>
    </div>

    <!-- Footer -->
    <footer>
        <p>© 2025 Photo Gallery. All rights reserved.</p>
    </footer>

    <script>
        // Filter functionality
        const filterButtons = document.querySelectorAll('.filter-btn');
        const galleryItems = document.querySelectorAll('.gallery-item');
        
        filterButtons.forEach(button => {
            button.addEventListener('click', function() {
                const filter = this.getAttribute('data-filter');
                
                // Update active button
                filterButtons.forEach(btn => btn.classList.remove('active'));
                this.classList.add('active');
                
                // Filter items
                galleryItems.forEach(item => {
                    if (filter === 'all' || item.getAttribute('data-category') === filter) {
                        item.classList.remove('hidden');
                    } else {
                        item.classList.add('hidden');
                    }
                });
            });
        });
        
        // Search functionality
        const searchBox = document.getElementById('searchBox');
        searchBox.addEventListener('input', function() {
            const searchTerm = this.value.toLowerCase();
            
            galleryItems.forEach(item => {
                const title = item.getAttribute('data-title').toLowerCase();
                const category = item.getAttribute('data-category').toLowerCase();
                
                if (title.includes(searchTerm) || category.includes(searchTerm)) {
                    item.classList.remove('hidden');
                } else {
                    item.classList.add('hidden');
                }
            });
        });
        
        // Lightbox functionality
        const lightbox = document.getElementById('lightbox');
        const lightboxImage = document.getElementById('lightboxImage');
        const lightboxCaption = document.getElementById('lightboxCaption');
        const lightboxCounter = document.getElementById('lightboxCounter');
        const lightboxClose = document.getElementById('lightboxClose');
        const lightboxPrev = document.getElementById('lightboxPrev');
        const lightboxNext = document.getElementById('lightboxNext');
        
        let currentImageIndex = 0;
        const visibleItems = () => Array.from(galleryItems).filter(item => !item.classList.contains('hidden'));
        
        galleryItems.forEach((item, index) => {
            item.addEventListener('click', function() {
                const allVisible = visibleItems();
                currentImageIndex = allVisible.indexOf(this);
                openLightbox(allVisible[currentImageIndex]);
            });
        });
        
        function openLightbox(item) {
            const img = item.querySelector('img');
            const title = item.getAttribute('data-title');
            
            lightboxImage.src = img.src;
            lightboxImage.alt = img.alt;
            lightboxCaption.textContent = title;
            
            const allVisible = visibleItems();
            lightboxCounter.textContent = `${currentImageIndex + 1} / ${allVisible.length}`;
            
            lightbox.classList.add('active');
        }
        
        lightboxClose.addEventListener('click', () => {
            lightbox.classList.remove('active');
        });
        
        lightboxNext.addEventListener('click', () => {
            const allVisible = visibleItems();
            currentImageIndex = (currentImageIndex + 1) % allVisible.length;
            openLightbox(allVisible[currentImageIndex]);
        });
        
        lightboxPrev.addEventListener('click', () => {
            const allVisible = visibleItems();
            currentImageIndex = (currentImageIndex - 1 + allVisible.length) % allVisible.length;
            openLightbox(allVisible[currentImageIndex]);
        });
        
        // Close on background click
        lightbox.addEventListener('click', function(e) {
            if (e.target === this) {
                this.classList.remove('active');
            }
        });
        
        // Keyboard navigation
        document.addEventListener('keydown', function(e) {
            if (!lightbox.classList.contains('active')) return;
            
            if (e.key === 'Escape') {
                lightbox.classList.remove('active');
            } else if (e.key === 'ArrowRight') {
                lightboxNext.click();
            } else if (e.key === 'ArrowLeft') {
                lightboxPrev.click();
            }
        });
    </script>
</body>
</html>

🎯 Key Features

🎯 Key Takeaways