How to create and image gallery using thumbnails and arrows
Categories:
Build an Interactive Image Gallery with Thumbnails and Navigation 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.
Gallery Structure: HTML Foundation
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"><</button>
<button class="nav-arrow next-arrow">></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.
src
attributes) are correct and that you have placeholder images in your images/
directory for testing. The data-index
attribute on thumbnails will be crucial for JavaScript to identify which image to display.Styling the Gallery: CSS for Visual Appeal
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.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
in your <head>
or before the closing </body>
tag.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"><</button>
<button class="nav-arrow next-arrow">></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.
style.css
file and your JavaScript into a script.js
file, linking them appropriately in your HTML. This improves organization and caching.