Problem
I needed to make a multi-page form, with slides, but without using too much js code like slick.js or the likes. So I tried to figure out how to make it really simple, but still cross-browser and responsive. I ended up with a small test using transform transitions. My question is: do you maybe see any relevant drawbacks on this technique?
The whole thing is based on 3 concepts:
-
If I use transforms, I’ll not have scrollbars.
-
I can use data attributes to both track the current slide and style (move) the main strip with css
-
For this specific project, I can safely assume I won’t never ever have more than 10 slides or so.
Notice that the demo slider does not loop. It’s intentional, since for this specific project I don’t want it to loop. Though, it would be fairly simple to make it loop, just change the current var accordingly.
The code:
HTML
<div class="main-box">
<div class="slide-box"><!-- mask -->
<div class="slides slides-7" data-current="1"><!-- strip -->
<div class="slide slide-1">1</div>
<div class="slide slide-2">2</div>
<div class="slide slide-3">3</div>
<div class="slide slide-4">4</div>
<div class="slide slide-5">5</div>
<div class="slide slide-6">6</div>
<div class="slide slide-7">7</div>
</div>
</div>
<div class="slide-buttons">
<button type="button" class="prev-button">prev</button>
<button type="button" class="next-button">next</button>
</div>
</div><!-- /main-box -->
CSS (scss)
.main-box{
max-width: 600px;
margin: 0 auto;
}
.slide-box{
overflow:hidden;
}
.slides{
background-color: #656565;
display: flex;
flex-wrap: nowrap;
transition: transform 300ms;
@for $i from 1 through 20{ // assuming slides won't never be > 20
&[data-current="#{$i}"]{ transform: translateX(-100% * ($i - 1)); }
}
.slide{
height: 300px;
min-width: 100%;
background-color: #ffb0b0;
&:nth-child(even){
background-color: #ff8181;
}
}
}//slides
JS (jquery)
var slide_strip = $('.slides');
var slides = slide_strip.find('> *');
var next_button = $('.next-button');
var prev_button = $('.prev-button');
next_button.on('click', function(e){ goto('next'); });
prev_button.on('click', function(e){ goto('prev'); });
function goto(direction){
var current = parseInt(slide_strip.attr('data-current'), 10);
if(direction == 'next'){
if(current >= slides.length) return;
current++;
} else {
if(current <= 1) return;
current--;
}
slide_strip.attr('data-current', current);
}
Solution
My question is: do you maybe see any relevant drawbacks on this technique?
I don’t see any drawbacks with the technique.
I do however see an improvement with the functions bound to the click handlers:
next_button.on('click', function(e){ goto('next'); });
prev_button.on('click', function(e){ goto('prev'); });
These can be simplified using partially applied functions:
next_button.on('click', goto.bind(null, 'next'));
prev_button.on('click', goto.bind(null, 'prev'));
And since the else
condition doesn’t really check the value of direction
you could cheat and just use goto
as the bound function on the previous button click hander:
prev_button.on('click', goto);
Additionally, while it may utilize a few more function calls (thus being slightly slower) the code within goto()
could be simplified using Math.min()
and Math.max()
:
if(direction == 'next'){
current = Math.min(slides.length, current + 1);
} else {
current = Math.max(current - 1, 0); // zero-based
}