DEV Community

Cover image for Rainbow infinite carousel tutorial (CSS)
Daniel Jiménez
Daniel Jiménez

Posted on

Rainbow infinite carousel tutorial (CSS)

We have seen infinite carousels in all directions and with all kinds of functions. The most typical one might be a website displaying the logos of its ambassadors, but there are many original uses for this, such as showcasing an art gallery. The only limit is your imagination!

I will explain the easiest way I have found to create this effect. If you want a sneak peek of the final result, check out my CodePen at the end of this file. ;)

The first thing we need to do for this project is to create two "divs." A friendly reminder: use the semantic tag that best suits your needs (aside, section or article could be great choices depending on your website). We are going to fill these divs with squares, but you can use whatever you like (images, etc.).

<section>
  <div class="container">
    <div class="carousel">
      <div class="square"></div>
      <div class="square"></div>
      <div class="square"></div>
      <div class="square"></div>
      <div class="square"></div>
      <div class="square"></div>
      <div class="square"></div>
    </div>
</section>
Enter fullscreen mode Exit fullscreen mode

If you've done this correctly, you won't see anything yet. ;) But that will change soon. Let's add some styles.

.carousel {
  display: inline-flex;
}

.carousel .square {
  height: 200px;
  width: 300px;
  margin: 0;
}
.carousel .square:nth-child(1) {
  background: red;
}
.carousel .square:nth-child(2) {
  background: orange;
}
.carousel .square:nth-child(3) {
  background: yellow;
}
.carousel .square:nth-child(4) {
  background: green;
}
.carousel .square:nth-child(5) {
  background: blue;
}
.carousel .square:nth-child(6) {
  background: indigo;
}
.carousel .square:nth-child(7) {
  background: violet;
}
Enter fullscreen mode Exit fullscreen mode

You can check

:nth-child() - CSS: Cascading Style Sheets | MDN

The :nth-child() CSS pseudo-class matches elements based on the indexes of the elements in the child list of their parents. In other words, the :nth-child() selector selects child elements according to their position among all the sibling elements within a parent element.

favicon developer.mozilla.org

if you need a refresher on this pseudo-class.

Now we have our carousel! Let's animate it. We really love rocking that CSS!

.carousel {
  display: inline-flex;
  animation: 5s infinite-carousel infinite linear;
}

@keyframes infinite-carousel {
  0% {
    transform: translateX(0%);
  }
  100% {
    transform: translateX(-100%);
  }
}
Enter fullscreen mode Exit fullscreen mode

You can check

@keyframes - CSS | MDN

La regla arroba @keyframes permite a los autores controlar los pasos intermedios en una secuencia de animación CSS mediante el establecimiento de keyframes (o puntos de trayectoria) a lo largo de la secuencia de animación que debe ser alcanzado por determinados puntos durante la animación. Esto le da un control más específico sobre los pasos intermedios de la secuencia de animación que se obtiene al dejar que el navegador maneje todo automáticamente.

favicon developer.mozilla.org

for more information.

The rainbow is moving, right? :) However, it still doesn't have the infinite effect, and when it ends, it jumps back to the same position. The keyframes name might seem a bit grand for a simple translation animation, but we will fix that soon.

Now comes the magic. The trick to making this effect infinite is to have not just one but two carousels playing the same animation simultaneously! The key is that both carousels are placed inline next to each other, so even though the animation restarts, we don't see the reset. We will achieve this with pseudo-classes and the overflow property.

Let's start by adding another carousel. Your final HTML should look like this:

  <section>
    <div class="container">
      <div class="carousel">
        <div class="square"></div>
        <div class="square"></div>
        <div class="square"></div>
        <div class="square"></div>
        <div class="square"></div>
        <div class="square"></div>
        <div class="square"></div>
      </div>
      <div class="carousel">
        <div class="square"></div>
        <div class="square"></div>
        <div class="square"></div>
        <div class="square"></div>
        <div class="square"></div>
        <div class="square"></div>
        <div class="square"></div>
      </div>
    </div>
  </section>
Enter fullscreen mode Exit fullscreen mode

Now, let's align them properly:

.container {
  overflow: hidden;
  padding: 40px 0;
  white-space: nowrap;
  position: relative;
  font-size: 0;
  line-height: 0;
}
Enter fullscreen mode Exit fullscreen mode

The white-space: nowrap; property ensures the elements are displayed inline. The overflow: hidden; prevents horizontal scrolling and keeps the effect visible. The font-size: 0; and line-height: 0; remove unwanted default browser styling for inline elements. If you use gap, images, or other elements, you may not need these adjustments.

Always refer to MDN when you need more details. This was the tricky part!

Now, let's create a smooth transition effect on each side of the carousel using the :before and :after pseudo-classes.

.container:before,
.container:after {
  position: absolute;
  top: 0;
  width: 20px;
  height: 100%;
  content: "";
  z-index: 2;
}

.container:before {
  left: 0;
  background: linear-gradient(to left, rgba(255, 255, 255, 0), white);
}

.container:after {
  right: 0;
  background: linear-gradient(to right, rgba(255, 255, 255, 0), white);
}
Enter fullscreen mode Exit fullscreen mode

The :before and :after pseudo-elements create two "divs" on each side. We use position: absolute; inside the .container, which has position: relative;. The width will depend on your design needs—most cases will require a wider gradient. Don't forget the content: ""; property; otherwise, the pseudo-elements won't appear.

And there you have it!

(Yes, the animation might be too fast. Adjust the animation duration to fit your needs. ;) )

Check out my example on CodePen:

Top comments (0)