Custom Scroller with 'Snap Points' using jQuery and jScrollPane

June 22, 2012 by jason

The Problem

A customer requested a custom content scroller that would showcase a grid of products on a single page. Unlike a typical scroller, they wanted horizontal only scrolling and the addition of "prev" and "next" links to advance the scroller one product column at a time. The challenge came from a user interface constraint that I imposed myself: I wanted to add "snap points" to the scroller. What do I mean by that? The content is arranged into columns of distinct product regions, and I have deliberately styled the scroller and the products so that exactly 3 columns will fit perfectly within the visible region. Any standard scroller will allow the user to advance the scroll region to an arbitrary position and leave it there. I want to ensure that at any time the scroller content is aligned within the viewer without any content partially cut-off on the edges.

The Details

After searching through the different jQuery scrollers available, I could not find anything that has this functionality out of the box. So next I had to think through the logic of how to do this with some custom javascript.

First, I need to determine the positions of the "snap points." In my case, the columns are even width so they can be pre-calculated positions along the scrollable region. (i.e. the snap points are located at "0, 1 column width, 2 column widths, ... etc.")

Now, when the user releases the scrollbar, look-up the position of the scrollable content and update the position to the nearest "snap point".

In order to follow the proposed flow, the scroller needs to meet the following constraints:

I must be able to determine the arbitrary position of the scroller at any time.

The scroller must have an event available to activate whenever the scroller is released.

The scroller must be able to be position controlled via javascript.

I decided to move forward with jScrollPane because of its API and excellent documentation. It has all of these abilities and more.

The Solution

In addition to just updating the position to the nearest "snap point," I wanted the scroller to feel organic and natural so I implemented smooth animations with easing to give the scroller the feel that it was sliding along a smooth track. This includes the "prev" and "next" buttons, who also reposition the scrollable region by increments of the column widths.

I developed this within the context of a Drupal website, but that is not a requirement. The following scripts are necessary for this scroller to function:

I've highlighted the necessary portions of the javascript to stand out. The rest of it is for adding the next & prev buttons and the product counter and adding their functionality to dynamically update. The last portion is the css necessary to make this function:

It would be fairly simple to adapt this solution for a set of content that is not uniform, by changing the logic of calculating the snap points to use the jQuery position() function to find the nearest column starting point. Since my application was known to be uniform, I went with the easiest solution to implement.