Custom Image Slider with Vanilla JavaScript

Jaxongir - Oct 30 '22 - - Dev Community

Hi guys, in today's post we're going to be building a custom image slider with HTML, CSS, and vanilla JavaScript. Hope you guys enjoy.

Source Code

Steps

1. Create directory for our app

Open the terminal and move to the folder that you'd like to create the project and type the following commands

mkdir image-slider
cd image-slider
Enter fullscreen mode Exit fullscreen mode

2. Create the folder structure

Once you've created the directory and opened it in the VS Code with code . Then we can start by creating the folder structure. You can take images from the github repository, or you can use any image that you like

cod
images
index.html
styles.css
index.js
Enter fullscreen mode Exit fullscreen mode

3. Create the structure of the app with pasting following HTML code

This is all the HTML we need for this app. We are using BEM class method for better code structure and styling. Once you pasted this to the code editor, open it in the browser

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Font Awesome icons -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <link rel="stylesheet" href="./styles.css">
    <title>Image Slider</title>
</head>
<body>
    <main class="image-slider">    
            <figure class="image-slider__image-box">
                <img src="./images/nature-1.webp" alt="image 1" class="image-slider__img image-slider__img--1">
                <img src="./images/nature-2.webp" alt="image 2" class="image-slider__img image-slider__img--2">
                <img src="./images/nature-3.webp" alt="image 3" class="image-slider__img image-slider__img--3">
                <img src="./images/nature-4.webp" alt="image 4" class="image-slider__img image-slider__img--4">
                <img src="./images/nature-5.webp" alt="image 5" class="image-slider__img image-slider__img--5">
            </figure>
        <button class="image-slider__btn image-slider__left-btn">
            <i class="fa-sharp fa-solid fa-chevron-left"></i>
        </button>
        <button class="image-slider__btn image-slider__right-btn">
            <i class="fa-sharp fa-solid fa-chevron-right"></i>
        </button>
        <div class="image-slider__round-box">
            <span class="image-slider__round image-slider__round--active"></span>
            <span class="image-slider__round"></span>
            <span class="image-slider__round"></span>
            <span class="image-slider__round"></span>
            <span class="image-slider__round"></span>
        </div>
    </main>
    <script src="./index.js" asyn></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

4. Now we add styles to make our app appealing

Paste the following CSS code

*,
*::before,
*::after {
    padding: 0;
    margin: 0;
}

.image-slider {
    overflow: hidden;
}
.image-slider__image-box {
    display: flex;
    transition: transform .3s ease-out;
}
.image-slider__img {
    display: block;
    flex: 1 0 100%;
    height: 100vh;
    width: 100vw;
}
.image-slider__btn {
    position: fixed;
    top: 50%;
    border: 0;
    background: transparent;
    font-size: 5rem;
    transform: translateY(-50%);
    color: #fff;
    cursor: pointer;
}
.image-slider__left-btn {
    left: 20px;
}
.image-slider__right-btn {
    right: 20px;
}
.image-slider__round-box {
    position: fixed;
    left: 50%;
    bottom: 20px;
    transform: translateX(-50%);
    display: flex;
    gap: 10px;
}
.image-slider__round {
    width: 50px;
    height: 10px;
    border: 2px solid #fff;
    border-radius: 5px;
    cursor: pointer;
}
.image-slider__round--active {
    background: #fff;
}
Enter fullscreen mode Exit fullscreen mode

5. Now we'll select all the HTML elements that are used in image sliding

// this selects image container all the images are in
const imageSliderBox = document.querySelector(".image-slider__image-box");
// this selects image slider left button which when clicked slides image to left
const imageSliderLeftBtn = document.querySelector(".image-slider__left-btn");
// this selects image slider right button which when clicked slides image to right
const imageSliderRightBtn = document.querySelector(".image-slider__right-btn");
// this selects the round buttons which are at the bottom of the page that when clicked slide image to that position
const imageSliderRounds = document.querySelectorAll(".image-slider__round");
// this selects all the slider images
const images = document.querySelectorAll("img");

// this is the image counter that keep track of the current image index that's being slided
let imageSlideCounter = 0;
Enter fullscreen mode Exit fullscreen mode

6. Now we add event to buttons to add ability to slide image to left and right

const slideImageToRight = () => {
  imageSlideCounter--;
  if (imageSlideCounter < 0) {
    imageSlideCounter = images.length - 1;
  }
  const slideImage = (imageSlideCounter) => {
    imageSliderBox.style = `transform: translateX(-${
      imageSliderBox.clientWidth * imageSlideCounter
    }px)`;
  };
};
const slideImageToLeft = () => {
  imageSlideCounter++;
  if (imageSlideCounter > images.length - 1) {
    imageSlideCounter = 0;
  }
  const slideImage = (imageSlideCounter) => {
    imageSliderBox.style = `transform: translateX(-${
      imageSliderBox.clientWidth * imageSlideCounter
    }px)`;
  };
};

// we add click event to left button, when it's clicked image is slided to left
imageSliderLeftBtn.addEventListener("click", slideImageToLeft);

// we add click event to right button, when it's clicked image is slided to right
imageSliderRightBtn.addEventListener("click", slideImageToRight);
Enter fullscreen mode Exit fullscreen mode

7. Adding image slide functionality to round buttons

Now we've managed to slide images to left and right. Now we add image slide to all 5 of those round buttons at the bottom of the page.

// inside the function we're updating image counter to current round button index which corresponds to image index. And also add class to the clicked image round to style it differently and removing class from unactive button to make it look the same as other inactive buttons
const updateCounter = (roundIndex) => {
  imageSlideCounter = roundIndex;
  imageSliderRounds.forEach((round) =>
    round.classList.remove("image-slider__round--active")
  );
  imageSliderRounds[imageSlideCounter].classList.add(
    "image-slider__round--active"
  );
};

// here we are adding click event to each round button and also passing it's index to event handler
imageSliderRounds.forEach((imageRound, index) =>
  imageRound.addEventListener("click", updateCounter.bind(null, index))
);

Enter fullscreen mode Exit fullscreen mode

8. Updating round buttons on left and right button click

So far we've been able to slide image to left and right. And also slide images on round button clicks. But their styles are only updating when we click them but not on left and right button click to do that we are going to move some of the code from "updateCounter" function to function named "updateImageRounds" and reuse that function on all those event handlers. We're also going to be moving image slide style to it's own function called slideImage, to make it reusable


// removes active class from inactive button and adds active class to currently active button
const updateImageRounds = (imageSlideCounter) => {
  imageSliderRounds.forEach((round) =>
    round.classList.remove("image-slider__round--active")
  );
  imageSliderRounds[imageSlideCounter].classList.add(
    "image-slider__round--active"
  );
};
const slideImage = (imageSlideCounter) => {
  imageSliderBox.style = `transform: translateX(-${
    imageSliderBox.clientWidth * imageSlideCounter
  }px)`;
};
const slideImageToLeft = () => {
  imageSlideCounter--;
  if (imageSlideCounter < 0) {
    imageSlideCounter = images.length - 1;
  }
  //   updateImageRounds(imageSlideCounter);
  slideImage(imageSlideCounter);
};
const slideImageToRight = () => {
  imageSlideCounter++;
  if (imageSlideCounter > images.length - 1) {
    imageSlideCounter = 0;
  }
  //   updateImageRounds(imageSlideCounter);
  slideImage(imageSlideCounter);
};
const updateCounter = (roundIndex) => {
  imageSlideCounter = roundIndex;
  updateImageRounds(imageSlideCounter);
  slideImage(imageSlideCounter);
};


imageSliderLeftBtn.addEventListener("click", slideImageToLeft);
imageSliderRightBtn.addEventListener("click", slideImageToRight);
imageSliderRounds.forEach((imageRound, index) =>
  imageRound.addEventListener("click", updateCounter.bind(null, index))
);

Enter fullscreen mode Exit fullscreen mode

9. Now we add automatic image slide

The last thing we're going to do is to add automatic image slide after the given interval. Add following code right before events

const initiateAutomaticImageSlide = () => {
  setInterval(slideImageToRight, 5000);
};
initiateAutomaticImageSlide();
Enter fullscreen mode Exit fullscreen mode

10 Hosting it on Github

Now we've finished building the project, we're going to be hosting it on the Github pages so we can share it with others. To do that do the following steps

  1. in the root directory of the app type: git init
  2. git add .
  3. git commit -m "init: complete building the app"
  4. create repository on the Github
  5. add that repository with git remote origin
  6. git push -u origin master
  7. refresh the github page
  8. go to github settings
  9. click pages in settings
  10. move none to master branch and click save
  11. after few minutes, github generate the live url of the website
  12. use that url however you want.

Summary

So in this post, we've built cool image slider with vanilla JavaScript and hosted it on github and made it live on the internet. If you've feedbacks, you can leave in the comments

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .