jQuery: vertical content slider

In this post I'll show you how to create a vertical content slider with jQuery and a couple of CSS rules. As you will see, the secret is not moving the slides, but the slider container itself. For that reason, we need to store the top offset of each slide in an array and then move the slider wrapper by using such offsets. We start with our markup, as usual:

<div id="slider">

 <div id="slide-wrapper">
 
   <div class="slide">...</div>
   <!--more slides-->
 
 </div>

</div>
<div id="slider-controls">...</div>

We have to set our main container to a well-defined width and height and the slide wrapper to an height that will be the sum of the heights of all slides. For that reason, we specify overflow: hidden on our main container so that only one slide at time will be visible:

#slider {
 width: 400px;
 margin: 0 auto;
 overflow: hidden;
 height: 300px;
}

#slide-wrapper {
 width: 100%;
 height: 1500px;
 position: relative;
}

div.slide {
 width: 100%;
 height: 300px;
 background: gray;
 color: #fff;
}

div.slide h2 {
 background: #c60;
 margin: 0;
 padding: 5px;
 text-align: center;
 text-transform: uppercase;
}

div.slide p {
 width: 80%;
 margin: 0 auto;
 padding: 0.5em 0 1em 0;
 line-height: 1.3;
}

#slider-controls {
 width: 105px;
 margin: 0.5em auto;
 height: 50px;
}

#slider-controls a {
 display: block;
 width: 50px;
 height: 50px;
 text-indent: -1000em;
}

#slider-controls #prev {
 background: url(prev.png) no-repeat;
 float: left;
}

#slider-controls #next {
 background: url(next.png) no-repeat;
 float: right;
}

The slide wrapper has also the declaration position: relative, so we can move it vertically. With jQuery, we first need to populate our array with all the slide offsets:

$(function() {

  var positions = [];
  var slideIndex = 0;
  
  var len = $('div.slide', '#slide-wrapper').length;

  $('div.slide', '#slide-wrapper').each(function(index) {
  
    var slide = index;
    var position = $(this).position().top;
    
    positions[slide] = position;
  
  
  });
  
  $('#prev', '#slider-controls').hide();

  // continues


});

We've also set an index to loop through our array and a limit to prevent our index from exceeding the array's length. Further, since our 'Previous' button is not required when the page loads, we hide it. Now we need to animate our slider:

// continues

$('#prev', '#slider-controls').click(function(event) {
  
    if(slideIndex > 0) {
    
      slideIndex--;
      
    } else {
    
      slideIndex++;
    
    
    }
    
    if(slideIndex == len) {
    
      slideIndex = 0;
    
    
    }
    
    
    
    $('#slide-wrapper').animate({
      top: - positions[slideIndex]
    }, 'slow');
   
    event.preventDefault();
  });
  
  
  
  $('#next', '#slider-controls').click(function(event) {
  
    
    
    slideIndex++;
    
    if(slideIndex == 1) {
    
      $(this).prev().show();
    
    }
    
    if(slideIndex == len) {
    
      slideIndex = 0;
    
    
    }
    
    
    
    $('#slide-wrapper').animate({
      top: - positions[slideIndex]
    }, 'slow');
   
    event.preventDefault();
  });



Basically, each time we click on a button, our slide index is incremented or decremented so that we can use it to pick a position from our array. Then we use the animate() method with a negative value for the top position to move our slider wrapper and show one slide at time. An extra care has been taken to make sure that our index won't exceed the length of the array. If so, we reset it to zero. You can see the demo below.

Demo

Live demo

This entry was posted in by Gabriele Romanato. Bookmark the permalink.

7 thoughts on “jQuery: vertical content slider”

  1. This is a really good tutorial.

    I'm a beginner in javascript and I am usually limited in what scripts I can use to simply redesigning them within their existing parameters(this I can do very well), but with this tutorial I was able to modify the script to suit my specific needs due to it's simplicity and explanations.

    Since I couldn't find any appropriate script elsewhere this was a big help. Great job and thank you.

  2. Hi Gabriele:
    I found this extremely useful too, thank you very much. I want to automate the slider so it scrolls every few seconds without having to click anything. Could you please give me a hint as to the best way to achieve this? Thanks!.

  3. You should create a timer, like so:

    var len = positions.length;
    var slideIndex = 0;

    var timer = setInterval(function() {

    counter++;

    if(counter == length) {
    counter = 0;
    }

    $('#slide-wrapper').animate({
    top: - positions[slideIndex]
    }, 1000);

    }, 1000);

    Bear in mind that the duration of the timer must match the duration of the animation. You could also use two setTimeout() functions:

    var timer = setTimeout(function() {

    // same code as above

    setTimeout(arguments.callee, 1000);

    }, 100);

    The second approach is to be preferred when you don't want to wait too much between each step. Note that the duration of the second call to setTimeout must always match the duration of the animation. :-)

    HTH

  4. wow, I didn't expect you to do all the work for me. :) Thanks very much, you are awesome. I used your code and (as a noob), spent the better part of the day creating an automated version of your slider. You can see the live demo here (it's the quotes at the bottom of the page):
    http://insighteditionscreative.com/

    This is my first time programming in js/jquery so if you can spare the time I would greatly appreciate your expert critique and advice, I'm sure you can find more than a few problems.

    Also, I didn't get why the durations have to match. I set my animation length to one second and the interval to six seconds, and it seems ok. Am I missing something? Thanks!

  5. Thanks for your comment. Coming from you it means a lot. Thanks for this blog, I've learned a lot. Take care! :)

Leave a Reply

Note: Only a member of this blog may post a comment.