Creating an Infinite Looping Image Carousel with CSS and JavaScript
Tags: javascript, css, carousel, beginners
Published: 2023-04-06 17:45:21

Creating a carousel with HTML, CSS, and JavaScript can be a fun and rewarding project for web developers. In this blog post, we'll explore the steps involved in creating a carousel and break it down into smaller tasks to make it easier to understand and implement.

This is what we will build

![end result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i74624hhqgc1e5pkx9ml.gif)

Pretty cool, huh?


![cool gif](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8vnv6g8f0nsmjj0qwc31.gif)

## Task 1: Creating a straight row with all the images lined horizontally centered

To start, we need a row of images that are horizontally centered. We can accomplish this by using CSS Flexbox. Here are the steps involved:

1. Create a `section` with the below styles, so that everything inside it is placed horizontally and vertically centered.
    
    ```css
    section{  
      height:100%;
      display:flex;  
      align-items:center;  
      justify-content:center;
    }
    ```
    
2. Create a container `div` with the class `carousel`, which contains all the images. We will also make this a flex item, and give it a max-width (optional).
    
    ```xml
    
    <section>
        <div class="carousel">
          <!-- Insert images here -->
        </div>
    </section>
    ```
    
3. Set the justify-content property of the container div to "center" to center all the images horizontally.
    
4. Set the gap property of the container div to add some space between the images.
    
    ```css
    .carousel {
      display: flex;
      max-width:1000px;
      gap:20px;      
    }
    ```
    
5. Let's also add the `transition` to carousel, as we will need this for animating the slide effect. The class `sliding-transition` will be added and removed using Javascript.
    
    ```css
    .carousel.sliding-transition {
      transition: transform 0.5s ease-in-out;
    }
    ```
    

## Task 2: Adding the Images

We will be using images from the free website [picsum.photos](http://picsum.photos) (The Lorem Ipsum for photos.)

1. Add &lt;img&gt; inside the carousel, and give them a class `carousel-image`
    
    ```xml
     <div class="carousel">
       <img src="https://picsum.photos/id/23/500" alt="Image 1" class='carousel-image'>
       <!-- Rest of the images in similar fashion -->
    </div>
    ```
    
2. Add any CSS you want, for styling the images. I will just go ahead with some box-shadow. (P.S. If you're facing problems with setting the width of the images, try using `flex-basis` instead.)
    
    ```css
    .carousel-image {
      -webkit-box-shadow: 5px 5px 5px 0px rgba(0, 0, 0, 0.5);
      -moz-box-shadow: 5px 5px 5px 0px rgba(0, 0, 0, 0.5);
      box-shadow: 5px 5px 5px 0px rgba(0, 0, 0, 0.5);
    }
    ```
    

## Task 3: Adding the background image with the blur and other effects

To make the carousel visually interesting, we can add a background image with a blur effect. We will place the currently selected image as the background image itself. Here's how to do it:

1. Create an &lt;img /&gt; element with the class `bg-image`.
    
    ```xml
    <section>
      <img ... class='bg-image' />
        <div class="carousel">
         <!-- images here -->
        </div>    
    </section>
    ```
    
2. Set the width and height of the image to 100% to make it fill the entire screen.
    
3. Add a blur effect using the CSS property `filter` and set it to `blur(8px)`.
    
4. We will also put a `position: absolute` and `inset:0` so that the image is placed behind the carousel. Added some other CSS which are for styling the image.
    
    ```css
    .bg-image {
      position:absolute;
      inset:0;
      width:100%;
      height:100%;
      filter: blur(8px);
      -webkit-filter: blur(8px);
      transform:scale(1.1);
      object-fit:cover;
    }
    ```
    

### Task 4: Designing the buttons for the left arrow and the right arrow

To allow users to navigate through the images, we need to create arrow buttons. Here's how to do it:

1. Create two buttons with the classes `left-arrow` and `right-arrow`, with `arrow-button` being common.
    
2. We need to position them `absolute`, and for that, we will need a div with `position: relative`.
    
3. Create a div with class `carousel-container` which will contain the carousel and the buttons.
    
    ```css
    .carousel-container {
      position: relative;
      overflow: hidden;
    }
    ```
    
    ```xml
    <section>
      <img ... class='bg-image' />
      <div class="carousel-container">
        <div class="carousel">
          <!-- images here -->
        </div>
        <button class="arrow-button left-arrow"></button>
        <button class="arrow-button right-arrow"></button>
      </div>
    </section>
    ```
    
4. Set the top of the buttons to 50% and use the `transform: translateY(-50%)` property to vertically center them.
    
5. Give the buttons a circular shape using the `border-radius` property.
    
6. These are the CSS used to add some extra look and feel.
    
    ```css
    .arrow-button {
      padding: 0;
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      color: #000;
      cursor: pointer;
      background: rgb(255, 255, 255, 0.3);
      width: 36px;
      font-size: 28px;
      display: flex;
      justify-content: center;
      align-items: center;
      border: none;
      border-radius: 50%;
      aspect-ratio: 1;
      -webkit-box-shadow: 5px 5px 5px -2px rgba(0, 0, 0, 0.5);
      -moz-box-shadow: 5px 5px 5px -2px rgba(0, 0, 0, 0.5);
      box-shadow: 5px 5px 5px -2px rgba(0, 0, 0, 0.5);
    }
    ```
    
7. We will use Unicode to create the arrows : `&#8249;` and `&#8250;`. Put them inside a span, with a width and height of 100%;
    
    ```css
    span {
      height: 100%;
      width: 100%;
    }
    
    .left-arrow {
      left: 20px;
    }
    
    .right-arrow {
      right: 20px;
    }
    ```
    
    ```xml
    <button class="arrow-button left-arrow"><span>&#8249;</span></button>
    <button class="arrow-button right-arrow"><span>&#8250;</span></button>
    ```
    

## Task 4: Creating the JavaScript to change the current image.

Bear with me, we are almost done. Phew!



![hang in there meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gi0vgt2n8yy6rn078qxp.png)

1. These are all the initializations:
    
    ```javascript
    const carousel = document.querySelector(".carousel");
    const backgroundImage = document.querySelector(".bg-image");
    
    const leftArrow = document.querySelector(".left-arrow");
    const rightArrow = document.querySelector(".right-arrow");
    
    let currentIndex = 0;
    let prevIndex;
    const images = document.querySelectorAll(".carousel-image");
    
    const totalImages = Object.keys(images).length;
    
    // const imageWidth = images[1].getBoundingClientRect().x;
    const imageWidth = 520;
    ```
    
    I am using a constant value of image width of 520 pixels, since there were some issues with Javascript loading late and calculating the width incorrectly in CodePen. I have commented the ideal approach for calculating width using `getBoundingClientRect()`.
    
    P.S. 520 Since &lt;img&gt; is 500 pixels wide and the flex box has a gap of 20px.
    
2. Here's the Pseudo Code for the Right Arrow :
    
    ```markdown
    1. When right arrow button is clicked, set prevIndex = currentIndex.
    2. Set currentIndex = (currentIndex + 1) % totalImages
    3. Now, to have the animation part, we will add the class `sliding-transition` to carousel.
    4. Move the carousel to the left by the width of one image using `translateX(-imageWidth pixels)`.
    5. Set the background image to the new current image.
    6. After the transition is completed:
       1. Move the prevIndex image to the end of `carousel` DOM.
       2. Remove the class `sliding-transition` from carousel.
       3. Remove the transform property as well, since we re-ordered the DOM.
    ```
    
    By removing the transition class, we ensure that the transition only occurs when we want it to and that we have full control over the carousel's movement.
    
    ```javascript
    rightArrow.addEventListener("click", () => {
      carousel.classList.add("sliding-transition");
    
      prevIndex = currentIndex;
      currentIndex = (currentIndex + 1) % totalImages;
    
      carousel.style.transform = `translateX(-${imageWidth}px)`;
      backgroundImage.src = images[currentIndex].src.slice(0, -3) + "1000";
    
      setTimeout(() => {
        carousel.appendChild(images[prevIndex]);
        carousel.classList.remove("sliding-transition");
        carousel.style.transform = "";
      }, 500);
    });
    ```
    
3. Now, here is the Pseudo Code for the Left Arrow (a tad bit more complex than the Right Arrow) :
    
    ```markdown
    1. When left button is clicked, set prevIndex = currentIndex.
    2. Set currentIndex = (currentIndex - 1 + totalImages) % totalImages
    Why modulo?
    In case currentIndex = 0, we need to do modulo, so as to implement the cyclical images.
    3. Move the carousel to the left by the width of one image using `translateX(-imageWidth pixels)`.
    4. Move the currentIndex image to the beginning of `carousel` DOM.
    5. Now, to have the animation part, we will add the class `sliding-transition` to carousel.
    6. Now make the carousel move to the right by width of one image (basically setting `translateX(0)`), or you can remove the transform property as well.
    7. Set the background image to the new current image.
    8. After the transition is completed, remove the class `sliding-transition` from carousel. (This can be done using timeout matching the animation's duration)
    ```

Here's the javascript code.    

    

```javascript
    leftArrow.addEventListener("click", () => {
      prevIndex = currentIndex;
      currentIndex = (currentIndex - 1 + totalImages) % totalImages;
      
      // Move Carousel to the left by one image, and insert the image at currentIndex at the beginning of carousel's DOM
      carousel.style.transform = `translateX(-${imageWidth}px)`;
      carousel.insertBefore(images[currentIndex], carousel.firstChild);
    
      // Now, let's start the transition effect, from -520 px to 0 px.
      setTimeout(() => {
        carousel.style.transform = "";
        carousel.classList.add("sliding-transition");
    
        // Changing the background Image
        backgroundImage.src = images[currentIndex].src.slice(0, -3) + "1000";
      }, 10);
    
      setTimeout(() => {
        // By removing the transition class, we ensure that the transition only occurs when we want it to and that we have full control over the carousel's movement.
        carousel.classList.remove("sliding-transition");
      }, 490);
    });   
```
    

Here's the CodePen if you want to see the full code and mess around with it.

{% codepen https://codepen.io/arindam404/pen/VwGgeOv %}

In conclusion, creating a carousel involves using HTML, CSS, and JavaScript to position and animate a series of images. By breaking down the process into smaller tasks, we can make it easier to understand and implement.