How to create an infinite image slider using CSS

Temani Afif

Written by Web Developer

October 4, 2022
How to create an infinite image slider using CSS

You must have seen those sliders of images that have an infinite loop animation. They are also called infinite carousels where all the images appear and disappear indefinitely. To create such sliders, most of the tricks rely on JavaScript or on duplicating the images. In this post, we will see how to do this without JavaScript and without duplicating any of the images.

We are going to use a few CSS tricks to build something like the below:

The Markup


The HTML code is as simple as a list of images within a container:

<div class="gallery">
  <img src="" alt="">
  <img src="" alt="">
  <img src="" alt="">
  <img src="" alt="">
</div>

As I said in the introduction, we are not going to duplicate any of the images so all of them are unique. We also don’t need any complex code structure like a lot of divs.

The Grid Configuration


We are going to rely on CSS Grid for the image placement.

.gallery  {
  display: grid;
  overflow: hidden;
}
.gallery > img {
  grid-area: 1/1;
  height: 200px;
  aspect-ratio: 1.5;
  object-fit: cover;
}

Nothing complex so far. We create a grid with specific dimensions (it’s up to you to adjust it as you want) then we place all the images above each other inside the same grid track using grid-area: 1/1.

The Animation


Let’s now tackle the important part of our code: The animation. The trickiest part here is to simulate the infinite loop without duplicating the image. We need to also consider the number of images.

In our case, we are using four images and we are going to split our animation into two steps. The first step is illustrated below:

Infinite Slider animation

The red dashes are the limit of our container. All the images need to move to the left by three times their size which will make the last image visible. This first step can be done by using transform: translate(-300%).

The next step is to move the first image right before the last one then translate it again until it becomes the visible image.

second step of the infinite slider animation

Our keyframes will look like below:

@keyframes r {
  /* Step 1 */
  0%    {transform: translate(0)}
  X%    {transform: translate(-300%)}
  /* Step 2 */
  (X + .01)% {transform: translate( 100%)}
  100%   {transform: translate(0)}
}

We first move our image to the left by -300%. Then we put it back to the right using 100%. Note that this should happen instantly that is why I am using X + .01. I am adding a tiny percentage to the previous state. Finally, we get back to the initial state.

Now we need to find the value of X. In the first step, the image is moving by three times its size (from 0% to -300%) while in the second step it’s moving by one time its size (from 100% to 0%). This means that the first step needs to stay three times longer than the second one. We have the following formulas:

T1 + T2 = 100%
T1 = 3*T2

Which give us

T1 = (4/3)*100% = 75%

The first step, need to run 75% of the keyframes so X needs to be equal to 75%. We can also omit the 0% and 100% from the keyframes since they are the default values and use only the following code:

@keyframes r {
  75%    {transform: translate(-300%)}
  75.01% {transform: translate( 100%)}
}

Oops, the animation seems to be broken and only one image is visible. Don’t worry, I didn’t make any mistakes and what you see is logical. Remember that in the Grid configuration we placed all the images above each other inside the same grid track. This means that all of them are moving together and only the top image is visible.

To fix this, we need to consider animation delays. The logic is as follows: We have fours images and the duration is defined by the variable --d so we will use var(--d)/4 and we define the delays like below:

  • The 1st image: calc(0*var(--d)/4)
  • The 2nd image: calc(1*var(--d)/4)
  • The 3rd image: calc(2*var(--d)/4)
  • The 4th image: calc(3*var(--d)/4)

Almost good but we have to wait for the animation to run. This is because we are using positive delays making the last image (the one at the top) start late. To fix this we simply make the delay negative and we are good:

The full code again:

.gallery  {
  --d: 6s; /* duration */
  
  display: grid;
  overflow: hidden;
  -webkit-mask: linear-gradient(90deg,#0000,#000 10% 90%,#0000);
}
.gallery > img {
  grid-area: 1/1;
  height: 200px;
  aspect-ratio: 1.5;
  object-fit: cover;
  animation: r var(--d) linear infinite;
}
.gallery > img:nth-child(2) {animation-delay: calc(1*var(--d)/-4)}
.gallery > img:nth-child(3) {animation-delay: calc(2*var(--d)/-4)}
.gallery > img:nth-child(4) {animation-delay: calc(3*var(--d)/-4)}

@keyframes r {
  75%    {transform: translate(-300%)}
  75.01% {transform: translate( 100%)}
}

With only a few lines of code, we get an infinite slider that works without duplicating the images. We can even do better and introduce another variable to make the code generic so it can work with any number of images.

For this we will rely on Sass:

$n:5; /* number of images*/

.gallery  {
  --d: 10s; /* duration */
  
  display: grid;
  overflow: hidden;
  width: 380px;
  -webkit-mask: linear-gradient(90deg,#0000,#000 10% 90%,#0000);
}
.gallery > img {
  grid-area: 1/1;
  width: 100%;
  aspect-ratio: 1.5;
  object-fit: cover;
  animation: r var(--d) linear infinite;
}
@for $i from 2 to ($n + 1) {
  .gallery > img:nth-child(#{$i}) {animation-delay: calc(#{(1 - $i)/$n}*var(--d))}
}
@keyframes r {
  #{100*($n - 1)/$n}% {transform: translate((1 - $n)*100%)}
  #{100*($n - 1)/$n + .01}% {transform: translate(100%)}
}

When we used 4 images we had to translate by -300% so with N images we need (1 - N)*100%. For the delays, we use a loop to set the value for all the images.

For the keyframes, remember the formulas we used:

T1 + T2 = 100%
T1 = 3*T2

Instead of 3, we will use N - 1 to get

T1 + T2 = 100%
T1 = (N - 1)*T2

Which will give us

T1 = 100% * N/(N - 1)

That’s it! With simple math, we transformed our code into a generic one that can work with any number of images:

Conclusion


Without JavaScript and without duplicating any of the images, we made an infinite image slider with an optimized code. Not to mention efficiency since we are animating only the transform property. To this, we added a touch of Sass to be able to easily control the number of images.

Frequently Asked Questions

Can you migrate my existing website over?

Yes, and without issue. Regardless of how many websites you’re managing, we’ll bring all of them under the Verpex wing free of charge. Just send us the details of your websites when you’ve signed up to get started.

How does Verpex help with my reseller hosting?

Our job doesn’t end once we’ve sold you the reseller space. In fact, we’re with you for the whole time you’re hosting with us, supporting both your needs and that of the customers you pick up along the way, whether you max out your cPanel account limit or not.

The Verpex team is at your disposal, acting as your essential support team 24/7. That means anything pertaining to hardware, the network, updates and configuration, security, and connectivity, is all handled by us.

Both you and your customers can focus on running your businesses while we take care of all maintenance and troubleshooting with expert technical support.

If I move my site to Verpex do I need to change domain name?

No, we make the transfer process easy and you can keep your current domain name.

Will the renewal price be more expensive now?

No. The pricing will stay the same as you had on Sharkhosting, you'll find no hidden costs here. All payment information is transparent and made clear from the outset.

Temani Afif
About the Author
Temani Afif

Temani Afif is an expert web developer, a content creator, and a CSS addict. He is the mastermind behind css-challenges.com, css-generators.com, css-only.art, css-articles.com, and a lot of CSS stuff. He's also an active contributor at Stack Overflow answering all kinds of CSS questions.

View all posts by Temani Afif
Discount

Enter Discount Code MOVEME During The SIGN UP Process To Get 90% Off Your First Month

with the discount code

MOVEME

Use Code Now
Jivo Live Chat