Slider Effects — Fade Out

Chapter 8 8 mins

Learning outcomes:

  1. What is the fade-out effect
  2. Implementing the effect

Introduction

After the first fade-out-fade-in effect that we considered in the previous chapter, it's now time to consider the fade-out effect.

Although by the name, the fade-out effect might seem fairly easy to implement, in practice it's a bit more complicated than fade-out-fade-in, involving concepts such as changing the stacking order of slides using z-index, preventing some properties from getting transitioned, and much more on this road.

So let's get into the real work once again!

How the effect works

First thing's first, let's see exactly how this effect works:

The current slide is faded out, showing the new slide beneath it.

And that's it.

At any given instance, we are only fading out one slide and that is the current one. As it fades out, the slide beneath it, which is the new slide, automatically becomes visible.

Now before proceeding any further, let's take sometime to think on how can we implement this effect.

Following are a couple of questions to test our knowledge about various ideas that'll eventually help us in implementing the fade-out effect.

Given the styles we applied to .slider_slide in the previous chapter, which property can we use to position the new slide at the back of the current one?

  • position
  • z-index
  • order

In implementing this fade-out effect, do we need to apply transition on the new slide, on the current slide, or on both of them?

  • New slide
  • Current slide
  • Both of them

Implementing the effect

We'll start off by reviewing .slider_slide's styles (given in the previous chapter) to see which styles we ought to add and remove before writing the logic of our fade-out effect.

Here's the CSS code:

.slider_slide {
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   opacity: 0;
   visibility: hidden;
}

.slider_slide:first-child {
   opacity: 1;
   visibility: visible;
}

In the fade-out-fade-in effect, we needed to perform the fade effect on both the current slide and the new slide, and likewise went with this very setup.

However, now it has to be changed since we don't want to fade-in the new slide — it just remains there behind the current slide.

Henceforth, we'll firstly remove the opacity declaration from both the given rulesets:

.slider_slide {
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   visibility: hidden;
}

.slider_slide:first-child {
   visibility: visible;
}

Next up, we'll do .... Well this is it — we just needed to remove the opacity property.

Now, it's time to start thinking about the classes to create in order to put the fade-out effect into action.

Following from the way fade-out works, the first thing we'll do is create a class that represents the new slide.

The new slide (which is to be ultimately displayed) needs to be positioned at the back of the current slide, hence we'll call the class as .slider_slide--back. It simply means that the new slide is at the back of the current slide.

Talking about the way to position the new slide at the back, this can be easily done using z-index. That is, the new slide gets a lower z-index while the current slide gets a higher z-index. As a result, the new slide gets stacked behind the current slide.

Luckily, we don't have to manually apply a z-index declaration to .slider_slide--back. Instead, we'll apply it to the class representing the current slide, which we'll consider in a while.

Apart from this, the new slide has to be made visible from the very beginning — there is no need to transitionally bring it in view. This means that our .slider_slide--back class needs no transition declaration. It just needs visibility: visible.

Altogether, we get to the following definition of .slider_slide--back:

.slider_slide.slider_slide--back {
   visibility: visible;
}

Recall that we need the .slider_slide class selector here in order to take up the precedence of the given styles. Otherwise, .slider_slide:first-child would win the precedence race and prevent any other similar styles from getting applied.

Technically, the class selector isn't needed for .slider_slide--back as it has the same styles as .slider_slide:first-child. However, to remain consistent, we give it as .slider_slide.slider_slide--back.

And with this, the first class for the fade-out effect is done. Let's now move over to deal with the class representing the current slide.

Recall that the current slide needs to be faded out, transitionally. This means that it needs to have the declarations visibility: hidden and opacity: 0 set, in addition to the transition property to smoothly change these properties.

Moreover, as we saw above, it needs to be positioned above the new slide. That could be simply done using the declaration z-index: 1.

The z-index of .slider_slide--back is 0. This is the default value for all elements on an HTML page.

Following from all this, the name we'll give to this class is .slider_slide--faded-out, clearly indicating that this slide has been (or has to be) faded out.

Here's the definition of .slider_slide--faded-out:

.slider_slide.slider_slide--faded-out {
   z-index: 1;
   opacity: 0;
   visibility: hidden;
   transition: 0.5s linear;
   transition-property: opacity, visibility
}

Restating it, z-index: 1 here serves to stack the current slide on top of the new one. The rest of the three properties take care of giving the fading out effect.

The most surprising declaration here is in line 6. The reason to give it is just to make sure that the transition doesn't apply over the z-index property, because if it does apply to z-index, the transition would behave weirdly.

With both these classes created, all that remains is to modify the navigateSlider() function to apply these respective classes to the current and new slides upon the slider's navigation.

Consider the code below:

function navigateSlider() {
   /* ... */

   slideElements[currentIndex].classList.remove('slider_slide--back');
   slideElements[currentIndex].classList.add('slider_slide--faded-out');

   slideElements[newIndex].classList.remove('slider_slide--faded-out');
   slideElements[newIndex].classList.add('slider_slide--back');

   currentIndex = newIndex;
}

As with the previous fade-out-fade-in effect, the current slide gets the class .slider_slide--back removed (if it already exists on it) and the class .slider_slide--faded-out added.

On the same lines, the new slide (which goes at the back) gets the class .slider_slide--faded-out removed (if it already exists on it) and the class .slider_slide--back added.

Let's see how is the effect working so far.

Live example

Simply perfect.