A dive into effects..

Uptil now we've seen a fairly decent number of features added to our simple slider including pagination, autoplay, progress bars and so on. However, what perhaps is the 'feel of sliding' is still missing from the slider. So how to add this feel of sliding?

Well the answer is very simple - using CSS transitions and animations together with some JavaScript.

In this unit we will discover what transitional effects can be given to this slider and how to actually program them. Effects such as fade, slide, squeeze may seem easy from the outside but laying out code to get them accomplished in the most compatible way is indeed a task which requires a decent amount of coding and designing experience.

The effects that we will particularly be looking over in detail are fade-out fade-in, fade out and fade-out slide-in and slide. In real, there can be literally tons of effects that can be given to a slider, but we consider only a few because either the rest are difficult to code and not worth the work or simply because they require the most latest and experimental technologies on the browser, that will otherwise fail on older bundles.

We do however get you to think through the effects in their respective chapters and actually learn the insights on how things really work together on the web. So why waste anymore time in reading all this and dive straight away into the work?

Introduction

The first effect that we will be considering in this chapter is what we call the fade out - fade in effect.

The way it operates is that the current slide in place is faded out and once it goes away completely the new slide is faded in. Hence the name fade out- fade in.

Which one of these CSS properties do you think we will need in the fade-out fade-in effect?
opacity
color
transform

So we will be needing the opacity property to get this whole effect in action.

But if you think for a moment only changing the opacity won't get the whole job done - we need one more property to get the slide disappear/appear. Any ideas?

When working with CSS transitions it is important for us to exactly determine the element on which we want the transitioning to happen. In this case since we need the individual slides to fade out and fade in and hence perform the transition, we would have to apply the transition property on them i.e on .slides.

So let's get this on the table first:

.slides {
    -webkit-transition: 0.5s linear;
    transition: 0.5s linear;
}

Proceeding further now we need to work on incorporating the fade out effect, and after that on to the fade in effect.

Fade out

Talking about fade-out, the way we can do it is to simply set opacity: 0 on the current slide, essentially giving a fading out effect on it, and visually hiding it.

slides[prevCounter].style.opacity = "0";

But we want to actually hide the slide as well, not just visually by setting opacity: 0.

What this means is that although, after applying opacity: 0 we can't visually see the slide in place, it's still there - opacity just makes it transparent! Hence any contained buttons, anchors will still be clickable, which we obviously don't want.

We need to actually hide the slide in some way or other - and the property display can help us in doing so!

So you might thinking that we can simply write the following code and get done:

slides[prevCounter].style.opacity = "0";
slides[prevCounter].style.display = "none";

But this won't work as expected. It would cause the transition to go away completely - simply no transition! The application of display removes transitioning of other properties.

Now what?

What we can do instead is to first set opacity: 0 on the current slide and once it completes only then set display: none.

In other words we want to delay the setting of display: none. Does something click your head from Javascript's final unit, after reading "delay". Can you recall Javascript Timers in particular setTimeout()?

This is just what we will need to perform the fade out effect properly. So let's see the complete code for this effect.

slides[prevCounter].style.opacity = "0";
setTimeout(function() {
    // delay this by 0.5s
    slides[prevCounter].style.display = "none";
}, 500);

First we fade out the current slide visually and then set a timeout for 0.5s. Note that this time is and must be the same as the duration for the transition, as shown above in the first code snippet. Finally in the timeout function we actually hide the current slide (line 3) completely using display: none.

And this completes the first cycle i.e fade out. Now onto the second one i.e fade in.

Fade in

The way we gave fade out right now, will just be the way we give fade in too, only with some slight changes. Firstly this time we will be going needing opacity: 1 to create a fading in transition and secondly instead of hiding the slide we will be showing it using display: block.

And as you suspected we can't just write:

slides[counter].style.display = "block";
slides[counter].style.opacity = "1";

.. because it will follow the same limitation as with the previous effect - no transition will be performed.

We basically need to to show the new slide first i.e set display: block on it, and then fade it in. We need to delay the fading in of the new slide. But when to show the new slide exactly together with the fade out effect we just created?

Well it's pretty simple..

We will start by fading out the current slide using opacity: 0 followed by setting display: block on the new slide, then wait for 500ms, and after that set display: none on the current slide and finally fade in the new slide using opacity: 1.

If you didn't understand this paragraph try reading it once more, carefully.

Gathering all these ideas takes us to the following complete navigateSlider() function:

slides[prevCounter].style.opacity = "0"; // fade out current slide
slides[counter].style.display = "block"; // show new slide
setTimeout(function() {
    // delay this by 0.5s
    slides[prevCounter].style.display = "none"; // hide current slide
    slides[counter].style.opacity = "1"; // fade in new one
}, 500);
Here we have shown just the code for the navigation of the slides within the function navigateSlider() - we haven't included the code for pagination. When you write this don't forget to include it!

And here is the fully working effect-based slider!

Fade out Fade in Effect

Improving things

Despite the fact that the effect we created above is working perfectly, it is usually recommended to keep CSS away from Javascript so that each concern remains seperate in its locations. Its hard to maintain CSS in two places, stylesheets and scripts, at the same time.

Therefore now we will be removing away the manual style changes in the script and use class toggles instead. Different CSS classes will serve to contain different styles which we can either add or remove from the slides very easily using Javascript's DOM attribute methods.

So what comes to our minds first is the following:

.fade-in {
    display: block;
    opacity: 1;
}
.fade-out {
    display: none;
    opacity: 0
}

We have a class fade-in for fading in slides and fade-out for fading them out. But the display property here again causes the no-transition trouble. We need to remove this display property from the classes.

But then how will we hide the slides? Can you think of any other way? Perhaps some other property which at least makes the slides visible/invisible? Well you've gotten the hint!

Which one of the following CSS properties can we use instead of display to show/hide the slide as well as not block any transitioning?
visibility
z-index
backface-visibility

That's right! We can use visibility in place of display. It's highly useful in conjunction with transitions since it doesn't bring them to a halt and furthermore even serves to hide the element - both the things we want.

So before anything we will first have to alter the styles for our .slides class by removing the display property:

.slides {
    visibility: hidden;
    opacity: 0;
    /* display: none; */
    /* other styles from the Basic Understanding chapter */
}
.slides:first-child {
    visibility: visible;
    opacity: 1;
    /* display: block */
}

Now that we've picked the right property to show/hide our slides and redefined .slides we can finally write the classes .fade-out and .fade-in:

.slides.fade-in {
    visibility: visible;
    opacity: 1;
    transition-delay: 0.5s;
}
.slides.fade-out {
    visibility: hidden;
    opacity: 0
}

And then the Javascript part goes like this:

slides[prevCounter].className = "fade-out"; // fade out current slide
slides[counter].className = "fade-in"; // fade in new slide

Go ahead and try out this slider below, noticing the issue with it.

Wrong Fade-out Fade-in Effect

The thing is that we don't really need two classes for our fade-out fade-in effect - they will cause more problem than benefit. In short, we can't easily make our effect work under the hood of two classes.

Instead, if you think on it carefully for a while you'll understand that our job can be well accomplished by just a single class - .fade-in.

Recall the fact that we need to first fade-out the current slide and then fade-in the new one. In other words we need to add the class .fade-out to the current slide followed by removing it from the new one.

For fading in a slide we can ADD this class and to fade it out we can simply REMOVE it. In this way it will be easier for us to write the Javascript to properly execute this idea. We always have to think efficiently when programming!

.slides.fade-in {
    visibility: visible;
    opacity: 1;
}
.slides.fade-out {
    visibility: hidden;
    visibility: hidden;
}

To delay the fading in of the new slide we will construct a new class .delay:

.slides.delay {
    -webkit-transition-delay: 0.5s;
    transition-delay: 0.5s;
}

For the slide navigation part of the function navigateSlider():

slides[prevCounter].classList.remove("delay"); // don't delay fade out
slides[prevCounter].classList.remove("fade-in"); // fade out current slide

slides[counter].classList.add("delay"); // delay fade in
slides[counter].classList.add("fade-in"); // fade in new slide

To get this all working without literally any problem the last thing we need to do is to initially give the first slide a class .fade-in so that it can be removed from the slide. Likewise we put the following code at the end of the script.

navigateSlider(); // give the first slide a class

And this accounts for the completion of the fade-out fade-in effect.

Uh, it was a heck of information! This fade-in class will be utilised in many of the coming effects chapters. When used in different ways this same class can make different sorts of effects in the fade category, so take a good note of it.

Fade-out Fade-in Effect