How to create and image gallery using thumbnails and arrows

Learn how to create and image gallery using thumbnails and arrows with practical examples, diagrams, and best practices. Covers javascript, jquery, html development techniques with visual explanati...

Build an Interactive Image Gallery with Thumbnails and Navigation Arrows

Hero image for How to create and image gallery using thumbnails and arrows

Learn how to create a dynamic image gallery using HTML, CSS, and JavaScript (jQuery) that features clickable thumbnails and intuitive navigation arrows for a seamless user experience.

Image galleries are a fundamental component of many websites, from e-commerce product pages to personal portfolios. A well-designed gallery enhances user engagement by providing an intuitive way to browse visual content. This article will guide you through building a responsive image gallery that includes a main display area, a strip of clickable thumbnails, and navigation arrows to cycle through images. We'll leverage HTML for structure, CSS for styling, and JavaScript (specifically jQuery for brevity) for interactivity.

The first step is to lay out the basic HTML structure for our gallery. We'll need a container for the main image, another for the thumbnails, and elements for the navigation arrows. Using semantic HTML5 elements will improve accessibility and maintainability.

<div class="gallery-container">
    <div class="main-image-display">
        <img id="mainImage" src="images/img1.jpg" alt="Gallery Image 1">
        <button class="nav-arrow prev-arrow">&lt;</button>
        <button class="nav-arrow next-arrow">&gt;</button>
    </div>
    <div class="thumbnail-strip">
        <img class="thumbnail active" src="images/img1.jpg" alt="Thumbnail 1" data-index="0">
        <img class="thumbnail" src="images/img2.jpg" alt="Thumbnail 2" data-index="1">
        <img class="thumbnail" src="images/img3.jpg" alt="Thumbnail 3" data-index="2">
        <img class="thumbnail" src="images/img4.jpg" alt="Thumbnail 4" data-index="3">
    </div>
</div>

Basic HTML structure for the image gallery.

With the HTML in place, we'll use CSS to style the gallery, making it visually appealing and responsive. This includes positioning the main image, arranging thumbnails, and styling the navigation arrows. We'll use Flexbox for layout flexibility.

.gallery-container {
    width: 80%;
    max-width: 900px;
    margin: 50px auto;
    border: 1px solid #ddd;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
    font-family: Arial, sans-serif;
}

.main-image-display {
    position: relative;
    width: 100%;
    height: 450px; /* Fixed height for main image area */
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #f0f0f0;
}

.main-image-display img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain; /* Ensures image fits without cropping */
}

.nav-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background-color: rgba(0, 0, 0, 0.5);
    color: white;
    border: none;
    padding: 10px 15px;
    cursor: pointer;
    font-size: 24px;
    z-index: 10;
    transition: background-color 0.3s ease;
}

.nav-arrow:hover {
    background-color: rgba(0, 0, 0, 0.8);
}

.prev-arrow {
    left: 10px;
}

.next-arrow {
    right: 10px;
}

.thumbnail-strip {
    display: flex;
    justify-content: center;
    padding: 10px;
    background-color: #eee;
    overflow-x: auto; /* Enable horizontal scrolling for many thumbnails */
}

.thumbnail {
    width: 80px;
    height: 60px;
    object-fit: cover;
    margin: 0 5px;
    cursor: pointer;
    border: 2px solid transparent;
    transition: border-color 0.3s ease, transform 0.2s ease;
}

.thumbnail:hover {
    transform: scale(1.05);
}

.thumbnail.active {
    border-color: #007bff;
    box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
}

CSS styles for the gallery layout, main image, thumbnails, and navigation arrows.

Adding Interactivity: JavaScript (jQuery)

Now for the dynamic part! We'll use JavaScript, with the help of jQuery, to handle image switching when thumbnails are clicked and when navigation arrows are used. We'll maintain an array of image sources and a currentIndex to keep track of the currently displayed image.

flowchart TD
    A[User loads page] --> B{Initialize Gallery}
    B --> C[Load image paths into array]
    C --> D[Display first image & activate first thumbnail]

    subgraph User Interaction
        D -- Click Thumbnail --> E{Update main image}
        E --> F[Update active thumbnail]
        F --> G[Update currentIndex]

        D -- Click Next Arrow --> H{Increment currentIndex}
        H --> I{Handle wrap-around (last to first)}
        I --> E

        D -- Click Prev Arrow --> J{Decrement currentIndex}
        J --> K{Handle wrap-around (first to last)}
        K --> E
    end

Flowchart illustrating the gallery's interactive logic.

$(document).ready(function() {
    const imageSources = [
        'images/img1.jpg',
        'images/img2.jpg',
        'images/img3.jpg',
        'images/img4.jpg'
    ];
    let currentIndex = 0;

    function updateGallery() {
        $('#mainImage').attr('src', imageSources[currentIndex]);
        $('.thumbnail').removeClass('active');
        $(`.thumbnail[data-index='${currentIndex}']`).addClass('active');
    }

    // Thumbnail click handler
    $('.thumbnail-strip').on('click', '.thumbnail', function() {
        currentIndex = parseInt($(this).data('index'));
        updateGallery();
    });

    // Next arrow click handler
    $('.next-arrow').on('click', function() {
        currentIndex = (currentIndex + 1) % imageSources.length;
        updateGallery();
    });

    // Previous arrow click handler
    $('.prev-arrow').on('click', function() {
        currentIndex = (currentIndex - 1 + imageSources.length) % imageSources.length;
        updateGallery();
    });

    // Initialize gallery on load
    updateGallery();
});

JavaScript (jQuery) code for gallery interactivity.

Putting It All Together: Complete Example

To see the full picture, here's how all the pieces fit into a single index.html file. Make sure you have an images folder with img1.jpg, img2.jpg, img3.jpg, and img4.jpg for this example to work correctly.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Interactive Image Gallery</title>
    <link rel="stylesheet" href="style.css"> <!-- Link to your CSS file -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <style>
        /* Inline CSS for demonstration, ideally in style.css */
        body {
            margin: 0;
            background-color: #f4f4f4;
        }
        .gallery-container {
            width: 80%;
            max-width: 900px;
            margin: 50px auto;
            border: 1px solid #ddd;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
            font-family: Arial, sans-serif;
        }
        .main-image-display {
            position: relative;
            width: 100%;
            height: 450px;
            overflow: hidden;
            display: flex;
            align-items: center;
            justify-content: center;
            background-color: #f0f0f0;
        }
        .main-image-display img {
            max-width: 100%;
            max-height: 100%;
            object-fit: contain;
        }
        .nav-arrow {
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            background-color: rgba(0, 0, 0, 0.5);
            color: white;
            border: none;
            padding: 10px 15px;
            cursor: pointer;
            font-size: 24px;
            z-index: 10;
            transition: background-color 0.3s ease;
        }
        .nav-arrow:hover {
            background-color: rgba(0, 0, 0, 0.8);
        }
        .prev-arrow {
            left: 10px;
        }
        .next-arrow {
            right: 10px;
        }
        .thumbnail-strip {
            display: flex;
            justify-content: center;
            padding: 10px;
            background-color: #eee;
            overflow-x: auto;
        }
        .thumbnail {
            width: 80px;
            height: 60px;
            object-fit: cover;
            margin: 0 5px;
            cursor: pointer;
            border: 2px solid transparent;
            transition: border-color 0.3s ease, transform 0.2s ease;
        }
        .thumbnail:hover {
            transform: scale(1.05);
        }
        .thumbnail.active {
            border-color: #007bff;
            box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
        }
    </style>
</head>
<body>

    <div class="gallery-container">
        <div class="main-image-display">
            <img id="mainImage" src="images/img1.jpg" alt="Gallery Image 1">
            <button class="nav-arrow prev-arrow">&lt;</button>
            <button class="nav-arrow next-arrow">&gt;</button>
        </div>
        <div class="thumbnail-strip">
            <img class="thumbnail active" src="images/img1.jpg" alt="Thumbnail 1" data-index="0">
            <img class="thumbnail" src="images/img2.jpg" alt="Thumbnail 2" data-index="1">
            <img class="thumbnail" src="images/img3.jpg" alt="Thumbnail 3" data-index="2">
            <img class="thumbnail" src="images/img4.jpg" alt="Thumbnail 4" data-index="3">
        </div>
    </div>

    <script>
        // Inline JavaScript for demonstration, ideally in script.js
        $(document).ready(function() {
            const imageSources = [
                'images/img1.jpg',
                'images/img2.jpg',
                'images/img3.jpg',
                'images/img4.jpg'
            ];
            let currentIndex = 0;

            function updateGallery() {
                $('#mainImage').attr('src', imageSources[currentIndex]);
                $('.thumbnail').removeClass('active');
                $(`.thumbnail[data-index='${currentIndex}']`).addClass('active');
            }

            $('.thumbnail-strip').on('click', '.thumbnail', function() {
                currentIndex = parseInt($(this).data('index'));
                updateGallery();
            });

            $('.next-arrow').on('click', function() {
                currentIndex = (currentIndex + 1) % imageSources.length;
                updateGallery();
            });

            $('.prev-arrow').on('click', function() {
                currentIndex = (currentIndex - 1 + imageSources.length) % imageSources.length;
                updateGallery();
            });

            updateGallery();
        });
    </script>

</body>
</html>

Complete index.html file combining HTML, CSS, and JavaScript for the gallery.