Introduction
When we talk about sliders, the most prevalent transitional effect is the slide effect. It's the most traditional of all effects.
In fact, as we shall discover later on in the latter part of this tutorial, the slide effect is also used when we are building touch interactive sliders that respond to swipe gestures.
Not only this but implementing slide effects, as a whole, is a lot easier as compared to the fade effects we saw in the Slider Effects — Fade-Out-Fade-In and the Slider Effects — Fade-Out chapters.
So, without wasting anymore of our time, let's get working!
How the effect works
Just like always, before moving on to coding the effect, we'll first spare some time to understand its mechanism.
So the way the slide effects works is that:
The effect works just as if we are scrolling the container of the slides with a scroll bar.
The entire container of .slider_slide
s translates itself to the left or right depending on the nature of the navigation. Note that the individual slides aren't transitioned directly, but instead their whole encapsulating container which in our case is .slider_slides-cont
back from the Slider Basics chapter.
And this it for the mechanism of the slide effect. Time for the implementation.
Setting things up
The effects we've been implementing thus far in this tutorial have got us to operate over the .slider_slide
class. However, in the slide effect, there is no point of working with .slider_slide
for the effect.
That's because in this effect, the whole container of the slides has to be moved with each navigation of the slider — not just any single slide therein. Hence, we need to work directly with the container of .slider_slide
which simply is .slider_slides-cont
.
Before hopping over to changing the navigateSlider()
function to implement the slide effect, we first need to make sure that the slides are positioned next to each other horizontally with only the first one shown.
How to do this?
Well, with the left: 0
declaration that we currently have in the CSS of our slider, all the slides are positioned on the exact same location, or more precisely, on top of each other.
In order to get them to be positioned next to each other, we firstly need to remove this left: 0
declaration from the .slider_slide
class. Moreover, we also need to remove the visibility: hidden
declaration in addition to removing the whole ruleset of .slider_slide:first-child
.
Shown below is the modified CSS code:
.slider_slide {
position: absolute;
top: 0;
width: 100%;
visibility: hidden;
}
.slider_slide:first-child {
visibility: visible;
}
Next up, we need to go over each slide and set the left
CSS property on it to an increasing multiple of 100%
, starting at 0%
with the first slide.
That is, the first slide gets left: 0%
; the second one gets left: 100%
; the third one gets left: 200%
; and so on and so forth.
With this application, all the slides get positioned next to each other horizontally, just as we want them to.
Now to accomplish this, we have two ways:
- Go to each slide element in the HTML and manually add the
left
style declaration. - Use JavaScript to automate this task.
Needless to say, we'll go with the latter here since it prevents us from having to do the tiring, repetitive and error-prone task of manually applying the left
style to each subsequent .slider_slide
element in the HTML markup.
So the idea is as follows: use a loop to iterate over all the slides, and then for each of them, compute the value to be given to the left
CSS property and then apply it.
Shown below is the code accomplishing this:
/* ... */
function navigateSlider() {
/* ... */
}
for (var i = 0; i < slidesLength; i++) {
slideElements[i].style.left = (100 * i) + '%';
}
/* ... */
Simple, wasn't this?
Let's see how the slider looks with this in place:
If your device has a large screen, then you would've surely been able to spot out the problem in the code above.
The slides are, no doubt, positioned just as we wanted them to be, however, they are overflowing the container .slider_slides-cont
.
How could we prevent this overflow?
One clearcut option is to set the declaration overflow: hidden
on .slider_slides-cont
. However, this won't work in the longer run.
Why?
Let's think about it very carefully....
If .slider_slides-cont
has overflow: hidden
set on it, moving it would mean that, visually, only the first slide moves. All the slides are contained within .slider_slides-cont
, hence hiding them by setting overflow: hidden
on this very container element would confine them inside it. If we move this element later on, all the slides therein would still remain hidden.
What we need here is another element to encapsulate the slides which will be moved when implementing the slide effect instead of moving .slider_slides-cont
.
Let's call this new element as .slider_slides-cont_wrapper
and put it inside .slider_slides-cont
.
Here's the new markup of our slider:
<div class="slider">
<div class="slider_slides-cont">
<div class="slider_slides-cont_wrapper">
<div class="slider_slide"><img src="pexels-stijn-dijkstra-2499786.jpg"></div>
<div class="slider_slide"><img src="pexels-addie-3152128.jpg"></div>
<div class="slider_slide"><img src="pexels-nextvoyage-3520548.jpg"></div>
</div>
</div>
<div class="slider_pagination"></div>
<button class="slider_nav">← Previous</button>
<button class="slider_nav">Next →</button>
</div>
Note that from now on, we'll use this very markup, containing the .slider_slides-cont_wrapper
element, no matter which effect we are trying to implement.
Anyways, with this new .slider_slides-cont_wrapper
element in place, we need to modify the CSS.
The styles previously applied to .slider_slides-cont
now need to be applied to .slider_slides-cont_wrapper
, except for the overflow: hidden
style.
Here's the new CSS:
.slider_slides-cont {
overflow: hidden;
position: relative;
padding-bottom: 56.25%;
}
.slider_slides-cont_wrapper {
position: relative;
padding-bottom: 56.25%;
}
Let's see how the slider looks now:
Problem solved. Good job.
Implementing the effect
Unlike the fade-out-fade-in or the fade-out effects that we covered in the last two chapters, implementing the slide effect is really easy.
We don't have to think about the current slide or the new slide in the implementation — it all happens on one single element and that's our new .slider_slides-cont_wrapper
element.
But before we can start coding, we need to settle on a couple of things:
- Which CSS property to use to move
.slider_slides-cont_wrapper
? - What value to give to that property upon each navigation?
For the first question, we'll use the transform
property, although we have other options as well such as left
and margin-left
. The reason for going with transform
is that it has an amazing animation performance compared to left
and margin-left
.
And in order to move the given element smoothly, we ought to apply a transition
on it.
Here's the CSS code extending the styles of .slider_slides-cont_wrapper
:
.slider_slides-cont_wrapper {
position: relative;
padding-bottom: 56.25%;
transition: 0.5s ease;
}
Great.
As for the second question, the answer is fairly straightforward: multiply newIndex
with -100
and apply the resulting value to the translateX()
function with the %
unit, inside the navigateSlider()
function.
Prior to that, however, we need a reference to the .slider_slides-cont_wrapper
element. This is done below:
var currentIndex = 0;
var newIndex = 0;
var slidesContWrapperElement = document.getElementsByClassName('slider_slides-cont_wrapper')[0];
var slideElements = document.getElementsByClassName('slider_slide');
var slidesLength = slideElements.length;
var paginationElement = document.getElementsByClassName('slider_pagination')[0];
var navElements = document.getElementsByClassName("slider_nav");
/* ... */
With the reference in hand, now we only need to head over to the navigateSlider()
and do rest of the business there:
function navigateSlider() {
/* ... */
slidesContWrapperElement.style.transform = 'translateX(' + (-100 * newIndex) + '%)';
currentIndex = newIndex;
}
As always, it's time to test the slider.
Simply perfect.