Remove Unused CSS

Check how much unused CSS you have on your website:

Quick & free. No signup needed.

CSS Background Slider

Jump To Slider Generator

Background Image Sliders are a widely used component of modern websites. In this article, we will demonstrate how we can build a slider with predefined, static images without using JavaScript at all.

Background Image Sliders are a widely used component of modern websites. In this article, we will demonstrate how we can build a slider with predefined, static images without using JavaScript at all.

Structurally, a slider is a container in which images appear with any transition effect such as fading, sliding, etc. The slider lets the website display multiple layers of business content in a fixed section. Therefore, sliders are of high marketing worth. For example, an e-store can put a slider containing all the top deals on the main landing page. It will catch the user’s attention immediately as well as inform them of all the top deals in a quick fashion, hence increasing the probability of a deal purchase.

Sliders can be either static or dynamic. A static slider has a predefined set of images that does not change with a page refresh. This article will demonstrate how we can build a static slider using HTML and CSS only. Dynamic sliders are out of the scope of this article and for them, you will need the support of JavaScript to change images at the run time.

Creating the Slider

Let’s write the skeleton of our slider. We are going to build one that hosts 5 images.

<div class="slider">
  <div class="slide"></div>
  <div class="slide"></div>
  <div class="slide"></div>
  <div class="slide"></div>
  <div class="slide"></div>
<div>

That’s it for the markup. The slider will be made functional by the magic of CSS.

Mechanics

Before we dive into the CSS implementation, let’s have an overview of how we will program the slider. The slider requires 2 main functions:

We are going to build the slider with the slide-in & slide-out transition effect. We want to write our CSS in a way that keeps the images independent of each other. This approach is easy to express, wrap your head around and debug. It requires some calculations which will follow. 

Initially, when thinking about the slider, you may be inclined towards considering slides relative to each other, with the current slide’s transition-out supposed to trigger the transition-in of the next slide. But as we will see, we can apply calculations on the slides independently and calibrate them in a manner that they work sequentially as part of a whole, giving the desired effect of the slides being knit with each other.

Animation Delay Calculations

Let’s dive into the calculations. We have the following data points that we need to work on and work with:

As mentioned before, we will define the animation for one slide only, and apply it to all the slides with a relative time offset in a manner that all slides appear to be sliding in and out relatively.

We have five slides. We want them to slide in and out sequentially so we want the first slide to have the least delay and the last slide to have the most delay. We have worked out the formula for calculating animation delays of all the slides as follows:

Delay(i) =  -(Animation_Duration * Slide_Number)/Total_Slides

where Slide_Number = 0 for the first slide and so on.

For this article, we will set the animation duration to 10 seconds. Here is a table representing the calculations for our 5-piece slider.

Slide Index Animation Delay (seconds)
0 0
1 -2s
2 -4s
3 -6s
4 -8s

You can observe in the calculations that we need to put a delay of animation-duration/total-slides between the slides.

As observed, our calculations require using negative animation-delay. The negative delay allows us to start the animation somewhere in the middle i.e beyond the starting state. If we use positive delays, our animation will start after the given time delay. 


Let’s explain the negative animation-delay with an example. Consider we have an infinite loop animation that moves an element to right 100 pixels in 5 seconds i.e. moving it 20px in the right direction each second. If we apply an animation delay of -2 seconds to it, the element will start off 40px (2 * 20) from its original position when the animation begins. This offset will apply in the first iteration only. Once the loop is complete, it will start from 0px in the subsequent iterations. If we have multiple elements, the one with the least delay will start off even further. For example, an element with a -4s delay of the same animation will start off 80 pixels (4*20) from its starting point in the first iteration. This is a valid use of the animation-delay property and not just a hack. (See W3 reference)

Coming back to our slide deck, we need a negative delay for the subsequent slides, or they would not slide in the first time around (they will just snap into view because the animation hasn't actually started yet). The negative delay is a little trick to start the animation immediately, but at a different point in the animation.

Animation Transition Calculations

Now that the slide delays are worked out, we need to calculate the transition percentages for the keyframes of our animation. The animation is broken down into the following steps:

Now we need to calculate the keyframe positions in the animation.

We have to decide how long you want the transition to be as a percentage of the total duration. For this article, we will use 5% as the transition-duration percentage ( 5% of a 10s animation is 0.5s, so our slides will take 0.5s to slide in/out of the view). Here is the formula:

According to this formula, our animation code is as follows:

@keyframes slide {
 0%, 15%, 100% {
   transform: translateX(0);
   animation-timing-function: ease;
 }
 20% {
   transform: translateX(-100%);
   animation-timing-function: step-end;
 }
 95% {
   transform: translateX(100%);
   animation-timing-function: ease;
 }
}

Our slider implementation is complete at this point. Next, we need to add the image addresses and the animation delays. We are using random, free images for this article.

.slider .slide:nth-child(1) {
  background-image: url("https://images.unsplash.com/photo-1595356700395-6f14b5c1f33f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80");
  animation-delay: 0;
}

.slider .slide:nth-child(2) {
  background-image: url("https://images.unsplash.com/photo-1591019052241-e4d95a5dc3fc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80");
  animation-delay: -2s;
}

.slider .slide:nth-child(3) {
  background-image: url("https://images.unsplash.com/photo-1543373014-cfe4f4bc1cdf?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80");
  animation-delay: -4s;
}

.slider .slide:nth-child(4) {
  background-image: url("https://images.unsplash.com/photo-1517430554953-a5ba4678fe85?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80");
  animation-delay: -6s;
}

.slider .slide:nth-child(5) {
  background-image: url("https://images.unsplash.com/photo-1583161178154-c362b3459d29?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80");
  animation-delay: -8s;
}

And we are done. The following codepen demonstrates the slider in action.

<div class="slider">
  <div class="slide"></div>
  <div class="slide"></div>
  <div class="slide"></div>
  <div class="slide"></div>
  <div class="slide"></div>
<div>
body {
  margin: 0;
}

.slider {
  overflow: hidden;
  width: 100vw;
  height: 100vh;
  position: relative;
}

.slider .slide {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-size: cover;
  background-position: center;
  animation: slide 10s infinite;
}

.slider .slide:nth-child(1) {
  background-image: url('https://images.unsplash.com/photo-1595356700395-6f14b5c1f33f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80');
  animation-delay: -0;
}

.slider .slide:nth-child(2) {
  background-image: url('https://images.unsplash.com/photo-1591019052241-e4d95a5dc3fc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80');
  animation-delay: -2s;
}
  
.slider .slide:nth-child(3) {
  background-image: url('https://images.unsplash.com/photo-1543373014-cfe4f4bc1cdf?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80');
  animation-delay: -4s;
}
  
.slider .slide:nth-child(4) {
  background-image: url('https://images.unsplash.com/photo-1517430554953-a5ba4678fe85?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80');
  animation-delay: -6s;
}

.slider .slide:nth-child(5) {
  background-image: url('https://images.unsplash.com/photo-1583161178154-c362b3459d29?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80');
  animation-delay: -8s;
}

@keyframes slide {
  0%, 15%, 100% {
    transform: translateX(0);
    animation-timing-function: ease;
  }
  20% {
    transform: translateX(-100%);
    animation-timing-function: step-end;
  }
  95% {
    transform: translateX(100%);
    animation-timing-function: ease;
  }
}

Note that this method of setup may seem too much. So we have set up a generator to help you calculate these values. We also included a fade animation, which uses the same principles as the slide animation (except it uses opacity and z-index to create the animation).

Background Slider Generator

Output
Preview
HTML

CSS


Even if you were to manually calculate all these values, most sites need only one slider on the homepage with a fixed set of images. So all we need to do is to set it up once and continue to use it for as long as we want. If we need a dynamic set of images, we will need to leverage JavaScript - a case that is out of the scope of this article.
To optimize the calculations, you may be tempted to use the variables and the calc() method for the animation delay. You could use some variables and calc() for the animation-delay settings, but they would still need to be set individually for each slide. You might think you could use CSS counters to get the index of each slide and set the delays for them all in one go, but we can not use counters in calc(). (See this StackOverflow thread). Moreover, It would be nice to set up the keyframe percentages using CSS variables and calc() as well, but we can only use the keywords from, to, or a percentage (CSS Animations Level 1), so we have to rely on manual calculations. But the good news is, we have to do it only once and can use it forever.

Conclusion

Background Sliders are a very useful component of the modern web. By leveraging the negative animation-delay and transition capabilities of CSS, we can build static image sliders without any JavaScript.