An image slider is a type of slideshow that displays a series of images in a horizontal or vertical arrangement. The images are displayed one after another, with a transition effect between each image. The images can be cycled through, and the user can navigate through the images using a set of navigation controls.
Other configurations can also be added to the slider like autoplay, pause on hover, zoom in and out, etc. But in this note, we will only focus on the basic configuration of the slider. And as a bonus, we will add a modal to the slider which will display the image in full size.
Hi guys and welcome to the third note in my Javascript Project Series, a series where I build 10+ Javascript projects, to test and build our Javascript coding skills. In this third note, we are going to learn how to build an image slider using CSS and JavaScript.
Note: All codes for each project in the series can be found on my GitHub and the deployed link to view all the projects is here.
Prerequisites
I am going to assume that you are already familiar with using Html, CSS, and JavaScript and also have a basic understanding of how JavaScript DOM Manipulation works. With that on hand, let's get coding.
Building an Image Slider from Scratch
Going into our favourite code editor, (I will be using VsCode), create 3 files called index.html
, style.css
and script.js
, and a folder called img
which will hold our images. (You can find all the images used in this tutorial here.) Now in your index.html file, copy the following code:
<!--* slider cntr -->
<div class="slider">
<!-- image -->
<img
class="slide-image"
src="./img/01-living-room-blue-theme.jpg"
alt="slide"
/>
<!-- the count and number of the images -->
<p>
<span class="slide-image-number">1</span> of
<span class="total-image-number">4</span>
</p>
<!-- previous btn -->
<div class="btn backward">
<span class="material-icons-outlined"> chevron_left </span>
</div>
<!-- next btn -->
<div class="btn forward">
<span class="material-icons-outlined"> chevron_right </span>
</div>
</div>
From the code above you can see that we have created a container called slider
and inside it we have created an image called slide-image
and a paragraph with two spans. We also created a previous button called backward
and a next button called forward
.
In our paragraph, the first span called slide-image-number
will display the number or position of the image that is currently being displayed and the second span called total-image-number
will display the total number of images that are in the slider.
The previous and next buttons as the name suggests are used to navigate back and forth through the images. I am using Google icons for the buttons. You can check it out here.
Viewed in the browser, our slider looks like this:
Now let's add some styling to it. In our style.css file, copy the following code:
/* heading */
h3 {
text-align: center;
}
/* slider container */
.slider {
padding: 20px;
background-color: rgba(255, 255, 255, 0.2);
position: relative;
margin: 40px auto;
max-width: 600px;
}
/* image */
.slide-image {
width: 100%;
min-height: 200px;
height: auto;
max-height: 400px;
padding: 10px;
margin: 0 auto;
}
/* paragraph holding the count and number of the images */
p {
text-align: center;
}
/* prev and next btns */
.btn {
position: absolute;
top: 50%;
font-size: 80%;
background-color: rgb(228, 231, 231);
border: solid 1px rgb(201, 199, 199);
padding: 5px;
cursor: pointer;
}
/* prev btn */
.backward {
left: 0px;
}
/* next btn */
.forward {
right: 0px;
}
It should now look like this:
At the moment, our slider is only showing one image. To add more images to the slider and be able to navigate through the images, we need to do that dynamically using JavaScript. So let's add some JavaScript to our script.js file.
// the variables of the image slider
const image = document.querySelector(".slide-image");
const imageNumber = document.querySelector(".slide-image-number");
const totalImageNumber = document.querySelector(".total-image-number");
const prevBtn = document.querySelector(".backward");
const nextBtn = document.querySelector(".forward");
// the image array
const images = [
"./img/01-living-room-blue-theme.jpg",
"./img/02-living-room-couch.jpg",
"./img/03-living-room-red-theme.jpg",
"./img/04-modern-kitchen.jpg",
];
// the index of the image on page load
let currentImage = 0;
// the image details that shows when the webpage loads
window.addEventListener("DOMContentLoaded", showImage);
// function to select and change the image details
function showImage() {
image.src = images[currentImage];
imageNumber.textContent = currentImage + 1;
totalImageNumber.textContent = images.length;
}
We created variables called image
, imageNumber
, totalImageNumber
, prevBtn
and nextBtn
. We also created an array called images
which will hold all the images that we want to display in the slider.
Next, we created a variable called currentImage
which will hold the index of the image in the array that is currently being displayed. This index will change when we click on our previous and next buttons which in turn changes the image that is being viewed as you will soon see.
We then wrote a function called showImage
that sets our image src to be the first on the list in the array using currentImage
which is initially equal to 0. We also set the contents of both the imageNumber
and the totalImageNumber
to be 1 and 4 which is the total number of images in the array respectively.
We then added an event listener to the window which will run the function showImage
when the webpage loads. Thus, letting the user view the first image in the array.
To confirm that our javascript code is working, let's go back into our index.html file and remove the values from our img src and spans.
<div class="slider">
<!-- image -->
<img class="slide-image" src="" alt="slide" />
<!-- the count and number of the images -->
<p>
<span class="slide-image-number"></span> of
<span class="total-image-number"></span>
</p>
...
</div>
Refreshing the browser, our slider still looks the same.
Let's add some functionality to our buttons.
// the next button function
nextBtn.addEventListener("click", function () {
currentImage++;
if (currentImage > images.length - 1) {
currentImage = 0;
}
showImage(currentImage);
});
// the prev button function
prevBtn.addEventListener("click", function () {
currentImage--;
if (currentImage < 0) {
currentImage = images.length - 1;
}
showImage(currentImage);
});
On our next button, we added an event listener called click
and added a function which sets the currentImage value to the index of the next image.
We, first of all, increase the value of currentImage
by 1 using the ++
operator. Then we check if the value of currentImage
is greater than the length of the array minus 1. If it is, we set the value of currentImage
to 0. If it isn't, we leave it as it is. This is because we want to loop back to the first image in the array. We then call the function showImage
with the currentImage value as an argument. This will display the next image in the array.
On our previous button, we added an event listener called click
and added a function which sets the currentImage value to the index of the previous image.
We first of all decrease the value of currentImage
by 1 using the --
operator. Then we check if the value of currentImage
is less than 0. If it is, we set the value of currentImage
to the length of the array minus 1. If it isn't, we leave it as it is. This is because we want to loop back to the last image in the array. We then call the function showImage
with the currentImage value as an argument. This will display the previous image in the array.
Going back to our browser, let's see if our navigation buttons are working.
Our buttons are now working and as you can see, we have built a slider that can display images in a slideshow and can also navigate through the images using the previous and next buttons.
Remember I said at the beginning of the note that I will be adding a bonus part to this note. We have come to that part. Yes, I am also going to add a modal to the slider. So that when the user clicks on any image, a modal will appear with the image that was clicked on. and the user will still be able to navigate through the images. Let's continue with the bonus part.
Adding a Modal to an Image Slider
It's quite simple really, and we can do it in a couple of lines of code along with some reusable code. First let's add a modal to our slider in our index.html file.
<!--* modal -->
<div class="modal">
<span class="close-modal material-icons-outlined"> close </span>
<!-- modal content -->
<div class="modal-content">
<!--* slider cntr -->
<div class="slider">
<!-- image -->
<img class="slide-image" src="" alt="" />
<!-- the count and number of the images -->
<p>
<span class="slide-image-number"></span> of
<span class="total-image-number"></span>
</p>
<!-- previous btn -->
<div class="btn backward">
<span class="material-icons-outlined"> chevron_left </span>
</div>
<!-- next btn -->
<div class="btn forward">
<span class="material-icons-outlined"> chevron_right </span>
</div>
</div>
</div>
</div>
From the code above, we can see that we created a container called modal
. We also created a container called modal-content
which will hold our slider. We then duplicated the slider container into the modal content container. A span called close-modal
was also added to be used to close the modal. Let's add some CSS to style our modal and its content.
/** modal */
.modal {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.649);
display: none;
justify-content: center;
align-items: center;
z-index: 10;
}
/* close modal btn */
.close-modal {
position: absolute;
top: 10px;
right: 10px;
background-color: #fff;
}
/* modal content */
.modal-content {
width: 100vw;
}
/* slider inside the modal */
.modal-content > .slider {
max-width: initial;
background-color: transparent;
}
.modal-content > .slider > .slide-image {
width: 100%;
max-width: 800px;
display: block;
min-height: initial;
max-height: 500px;
height: auto;
}
/* paragraph holding the count and number of the images in the slider */
.modal-content p {
color: #fff;
}
Currently, our modal is not visible. We have to write some Javascript code to make it visible. We also need to refactor our code to accommodate the modal.
Refactoring our variables
// the variables of the image slider
const image = document.querySelectorAll(".slide-image");
const imageNumber = document.querySelectorAll(".slide-image-number");
const totalImageNumber = document.querySelectorAll(".total-image-number");
const prevBtn = document.querySelectorAll(".backward");
const nextBtn = document.querySelectorAll(".forward");
const modal = document.querySelector(".modal");
const closeBtn = document.querySelector(".close-modal");
We refactored our image
, imageNumber
, totalImageNumber
, prevBtn
, nextBtn
, using querySelectorAll instead of querySelector. This is so that we can also target them in our modal content container also. We also added a variable called modal
which is the modal container. And a variable called closeBtn
which is the close modal button.
Refactoring our showImage function
// function to select and change the image details
function showImage() {
for (i of image) {
i.src = images[currentImage];
i.addEventListener("click", function () {
modal.style.display = "flex";
});
}
for (i of imageNumber) {
i.textContent = currentImage + 1;
}
for (i of totalImageNumber) {
i.textContent = images.length;
}
}
We also refactored our showImage
function. We added a for loop to loop through all the images. An event listener was also added to each image so that when the user clicks on an image, we display the modal.
A for loop was also added to loop through all the image numbers and the total image numbers so as to set the correct image number and total image number on both sliders.
Therefore, when the function is called, it not only runs on our image slider, it runs on the slider inside the modal as well.
Let's refactor our navigation buttons.
Refactoring our previous and next button functions
// the next button function
for (i of nextBtn) {
i.addEventListener("click", function () {
currentImage++;
if (currentImage > images.length - 1) {
currentImage = 0;
}
showImage(currentImage);
});
}
// the prev button function
for (i of prevBtn) {
i.addEventListener("click", function () {
currentImage++;
if (currentImage > images.length - 1) {
currentImage = 0;
}
showImage(currentImage);
});
}
So the for loop is also added to loop through all the next buttons and the prev buttons. And the event listener is added to each button.
Let's write some more code to close the modal.
// close the modal
closeBtn.addEventListener("click", function () {
modal.style.display = "none";
});
An event listener is added to the close modal button. When the user clicks on the button, the modal will be closed.
Now let's test our code.
Everything is working fine. Yay!
Our image slider is working perfectly along with the navigation buttons. When we click on any of the images, the modal will be displayed with the enlarged image that was currently clicked on. We can also navigate through the images using the next and prev buttons as well.
We can also close the modal by clicking on the close modal button. When we close the modal, the image slider will be back to its original state showing the image that we were currently on before closing the modal.
Conclusion
We have seen how easy it is to build an image slider with minimal CSS and vanilla Javascript code.
We also added simple navigation buttons to help us navigate through the images and added a paragraph to display the current image number and total image number.
We also saw how easy it is to create a modal that can be opened by clicking on any of the images and can be closed by clicking on the close modal button.
We also made the images in the slider and modal correspond to each other irrespective of each other or where they are being viewed.
We not only learnt how to build a slider, we learnt how to build a modal as well.
And that's the end of this tutorial. I hope you liked it. If you have any questions or comments, please feel free to comment below or contact me via the links below.
Till next time guys, Byeee!
Connect with me on
Twitter | LinkedIn | Instagram.
If you like my notes and would like to support me, you can buy me a coffee on ByMeACoffee. I love the taste of coffee.🥰