DEV Community

loading...
Cover image for An infinite/circular carousel with css flex and little JS

An infinite/circular carousel with css flex and little JS

technikhil314
Eating. Playing drums. Making mistakes. Trying to give my experience. Failing to explain and making new mistakes. All while coding. All for learning
Updated on ・2 min read

Lately I have been playing a lot with css (and finally yes I get to do what I love) I was actually thinking of several applications of flex order property. Last usecase I found helps to solve a small accessibility issue in signup/NDA forms head here to see what it was.

This one tries to create a bare minimum infinite/circular carousel with as less as 70 lines of code all included HTML,CSS,JS

What do I mean by circular/infinite carousel?

Its a carousel that has n number of slides and it keeps scrolling to right side (for LTR languages) and (n+1)th chilid is again 1st child.

So lets start

  • I will be using css flex, flex order, scroll-snap and little bit of plain JS to make our carousel autoscroll.
  • This is going to be a bare minimum carousel

Lets take a look at basic HTML and css for our carousel

<div class="carouselWrapper">                
    <div class="carouselContainer">
        <div class="carouselItem">
            <img height="100px" width="100%" src="//via.placeholder.com/1000x100/FFFF00/000000/?text=Carousel+Item+21"
                alt="" />
        </div>
        <div class="carouselItem">
            <img height="100px" width="100%" src="//via.placeholder.com/1000x100/FF0000/FFFFFF/?text=Carousel+Item+22"
                alt="" />
        </div>
        <div class="carouselItem">
            <img height="100px" width="100%" src="//via.placeholder.com/1000x100/00FF00/000000?text=Carousel+Item+23"
                alt="" />
        </div>  
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

and here is the css

.carouselWrapper {
  position: relative;
}

.carouselContainer {
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
}
.carouselContainer .carouselItem {
  flex-grow: 0;
  flex-shrink: 0;
  max-width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

Check the codepen

You can get rid of that horizontal scroll bar using following css and add scroll snap to it

.carouselContainer {
  display: flex;
  flex-wrap: nowrap;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  overflow-x: auto;
  scrollbar-width: 0;
  scrollbar-color: transparent transparent;
}
.carouselContainer::-webkit-scrollbar {
  display: none;
}
.carouselContainer .carouselItem {
    flex-grow: 0;
    flex-shrink: 0;
    max-width: 100%;
    // we are telling browser to align each item centrally to 
    // screen as it scrolls into viewport
    scroll-snap-align: center;
}
Enter fullscreen mode Exit fullscreen mode

We have added following property scroll-snap-type: x mandatory; to carouselContainer class

here We are telling browser to apply scroll snap on
horizontal axis and make it manadatory to scroll one item
fully to snap behaviour to kick in.
check more details here

We are also adding scroll-snap-align: center; property to carouselItem class

we are telling browser to align each item centrally to
screen as it scrolls into viewport

Now lets add little bit of javascript

let index = 0;
const speed = 5;
const numberOfSlides = 3;
const carouselContainer = document.querySelector(".carouselContainer");
const carouselItemWidth = carouselContainer.scrollWidth / numberOfSlides;
setInterval(() => {
  carouselContainer.scrollBy(carouselItemWidth, 0);
  timeoutId = setTimeout(() => {
    index = index % numberOfSlides;
    let childToMove = carouselContainer.querySelectorAll(`.carouselItem`)[
      index
    ];
    // The line below move the item to end of carousel by 
    // manipulating its flex order
    childToMove.style.order =
      childToMove.style.order && childToMove.style.order === 0
        ? 1
        : +childToMove.style.order + 1;
    index++;
    clearTimeout(timeoutId);
  }, 1000);
}, speed * 1000);
Enter fullscreen mode Exit fullscreen mode

And woohoo our carousel is running

Let me know your thoughts on this.

Discussion (0)