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);
}
1 Answer 1
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
}
var slide_strip = $('.slides');
var slides = slide_strip.find('> *');
var next_button = $('.next-button');
var prev_button = $('.prev-button');
next_button.on('click', goto.bind(null, 'next'));
prev_button.on('click',goto);
function goto(direction){
var current = parseInt(slide_strip.attr('data-current'), 10);
if(direction == 'next'){
current = Math.min(slides.length, current + 1);
} else {
current = Math.max(current - 1, 0);
}
slide_strip.attr('data-current', current);
}
.main-box {
max-width: 600px;
margin: 0 auto;
}
.slide-box {
overflow: hidden;
}
.slides {
background-color: #656565;
display: flex;
flex-wrap: nowrap;
transition: -webkit-transform 300ms;
transition: transform 300ms;
transition: transform 300ms, -webkit-transform 300ms;
}
.slides[data-current="1"] {
-webkit-transform: translateX(0%);
transform: translateX(0%);
}
.slides[data-current="2"] {
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
.slides[data-current="3"] {
-webkit-transform: translateX(-200%);
transform: translateX(-200%);
}
.slides[data-current="4"] {
-webkit-transform: translateX(-300%);
transform: translateX(-300%);
}
.slides[data-current="5"] {
-webkit-transform: translateX(-400%);
transform: translateX(-400%);
}
.slides[data-current="6"] {
-webkit-transform: translateX(-500%);
transform: translateX(-500%);
}
.slides[data-current="7"] {
-webkit-transform: translateX(-600%);
transform: translateX(-600%);
}
.slides[data-current="8"] {
-webkit-transform: translateX(-700%);
transform: translateX(-700%);
}
.slides[data-current="9"] {
-webkit-transform: translateX(-800%);
transform: translateX(-800%);
}
.slides[data-current="10"] {
-webkit-transform: translateX(-900%);
transform: translateX(-900%);
}
.slides[data-current="11"] {
-webkit-transform: translateX(-1000%);
transform: translateX(-1000%);
}
.slides[data-current="12"] {
-webkit-transform: translateX(-1100%);
transform: translateX(-1100%);
}
.slides[data-current="13"] {
-webkit-transform: translateX(-1200%);
transform: translateX(-1200%);
}
.slides[data-current="14"] {
-webkit-transform: translateX(-1300%);
transform: translateX(-1300%);
}
.slides[data-current="15"] {
-webkit-transform: translateX(-1400%);
transform: translateX(-1400%);
}
.slides[data-current="16"] {
-webkit-transform: translateX(-1500%);
transform: translateX(-1500%);
}
.slides[data-current="17"] {
-webkit-transform: translateX(-1600%);
transform: translateX(-1600%);
}
.slides[data-current="18"] {
-webkit-transform: translateX(-1700%);
transform: translateX(-1700%);
}
.slides[data-current="19"] {
-webkit-transform: translateX(-1800%);
transform: translateX(-1800%);
}
.slides[data-current="20"] {
-webkit-transform: translateX(-1900%);
transform: translateX(-1900%);
}
.slides .slide {
height: 300px;
min-width: 100%;
background-color: #ffb0b0;
}
.slides .slide:nth-child(even) {
background-color: #ff8181;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<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 -->
Explore related questions
See similar questions with these tags.