jQuery Smooth Div Scroll by Thomas Kahn

Smooth Div Scroll is a jQuery plugin that scrolls content horizontally left or right. Apart from many of the other scrolling plugins that have been written for jQuery, Smooth Div Scroll does not limit the scroling to distinct steps. As the name of the plugin hints, scrolling is smooth. There are no visible buttons or links since the scrolling is done using hot spots within the scrollable area or via autoscrolling. Unobtrusive and smooth is the key here.

Table of contents

  1. How it works
  2. Quick demo
  3. Key features
  4. More examples!
  5. Parameters
  6. The CSS
  7. Dependencies
  8. Download
  9. Help and support
  10. Newsletter
  11. FAQ
  12. Version history
  13. To-do (the next version)
  14. Copyright, license and all that
  15. About me
  16. Do you want to help or give it a rating?

How it works

Smooth Div Scroll works by scrolling one div (scrollableArea) inside another div (scrollWrapper). Ether two hotspot div's are used to trigger the actual scrolling (scrollingHotSpotLeft and scrollingHotSpotRight) or you can let it autoscroll.

Illustration showing the different elements of Smooth Div Scroll

The scrollWrapper determines how much of the scrollableArea div that should be visible - everything outside the scrollWrapper is hidden from the user. The scrollWrapper is always placed inside a containing div and it's upon this containing div that we apply the Smooth Div Scroll plugin. The containing div also determines the width and height. Then the width of scrollWrapper is set to 100%, giving it the same width as the containing element.

You are in full control of the scrolling behavior. The scrolling can be controlled using the hot spots, or you can disable the hot spots alltogether and just let it autoscroll - like a running ticker or slideshow. There's also a mixed mode where Smooth Div Scroll will autoscroll as long as the user does not interact with the scroller (use the hot spots). As soon as the user moves the pointer over one of the hot spots, the autoscrolling will stop and the user takes control of the scrolling. The mixed mode is excellent for showing the user that there is a part of the page that is scrollable and if you combine it with having visible hot spots for the first 10-15 seconds after the page has loaded, your users will instinctively understand how to interact with the scroller.

Scrolling using the hot spots

Moving the mouse pointer over scrollingHotSpotLeft makes the scrollable area move to the right, giving the impression that the user is scrolling left. Moving the mouse pointer over scrollingHotSpotRight makes the scrollable area move to the left, giving the impression that the user is scrolling right.

Autoscrolling

As I've mentioned earlier, autoscrolling comes in two flavors:

Speaking of parameters, there are several that you can use to customize the autoscrolling speed and behavior.

Speed is controlled using the parameter autoScrollSpeed. A speed of 1-2 is slow, 3-4 is medium, 5-13 is fast and anything higher is superfast. Then there is direction and certain scrolling beaviors. This is controlled using the parameter autoScrollDirection. You can choose between four different settings:

Even if you have set autoscroll to always, it's nice to give the user the option to stop the scrolling momentarily if there is something that he/she wants to take a longer look at. The parameter pauseAutoScroll is the one you'll use for that. Choose between the values mousedown and mouseover or just leave it blank for no pausing possibilities. If you choose mousedown autoscrolling will pause as long as the user holds down the mouse button while the pointer is over the scroller. If you choose mouseover, the user only needs to move the pointer over the scroller to pause the autoscrolling. When the pointer exits the scroller, autoscrolling will continue.

Back to table of contents

Quick demo

Here's a quick demo of Smooth Div Scroll in action. The jQuery code for this demo looks like this:


<script type="text/javascript">
		$(function() {
			$("div#makeMeScrollable").smoothDivScroll({scrollingSpeed: 12, mouseDownSpeedBooster: 3, autoScroll: "onstart", autoScrollDirection: "endlessloop", autoScrollSpeed: 2, visibleHotSpots: "onstart", hotSpotsVisibleTime: 9, startAtElementId: "startAtMe"});
		});
</script>

I've set some parameters that are not default for this demo:

The result is this:

Demo image Demo image Demo image Demo image Demo image

In the demo above the XHTML-code looks like this:


<div id="makeMeScrollable">
	<div class="scrollingHotSpotLeft"></div>
	<div class="scrollingHotSpotRight"></div>
	<div class="scrollWrapper">
		<div class="scrollableArea">
			<img src="images/demo/image_1.jpg" alt="Demo image" />
			<img src="images/demo/image_2.jpg" alt="Demo image" />
			<img src="images/demo/image_3.jpg" alt="Demo image" id="startAtMe" />
			<img src="images/demo/image_4.jpg" alt="Demo image" />
			<img src="images/demo/image_5.jpg" alt="Demo image" />
		</div>
	</div>
</div>

As you can see there is a surrounding div with the id makeMeScrollable. This is the element that I turn into a Smooth Div Scroll. You can also see the element that I've given the ID startAtMe so I can tell Smooth Div Scroll that I want it to start the scrolling at this element using the parameter startAtElementId: "startAtMe".

The jQuery code looks like this:


$(function() {
	$("div#makeMeScrollable").smoothDivScroll({scrollingSpeed: 12, mouseDownSpeedBooster: 3, autoScroll: "onstart", autoScrollDirection: "endlessloop", autoScrollSpeed: 2, visibleHotSpots: "onstart", hotSpotsVisibleTime: 9, startAtElementId: "startAtMe"});		
});

In this example I've used many of the available parameters. You'll find all the parameters described here.

Please note that you may have to give the elements that you put inside the scrollable area some styling to make sure that they are positioned like you want them. In the demo above I want all the images on a single row, one after the other, with no margin or padding. So I add a style to my CSS that looks like this:


	#makeMeScrollable div.scrollableArea *
	{
		position: relative;
		float: left;
		margin: 0;
		padding: 0;
	}

If you skip this, it might still work but it's good practice to always style the elements inside scrollableArea to make sure the behave like they are supposed to. For example, if you remove the above styling from this demo, an "invisible" space will be added between the images (assuming you keep the tags on separate lines in the code). By invisible I mean that the space is visible in the browser window but none of the jQuery functions will recognize and include this space in the total width calculation. Needless to say, this confuses the function that calculates the total width and the result is often that there is not enough room for the last element and it is not shown. By floating all images and removing all padding and margin I prevent this error.

Back to table of contents

Key features

Here are some of the key features that I've incorporated into the design. They are not parameters or other settings but rather basic design principles and behaviors:

Back to table of contents

More examples!

Here are some more examples of how SmoothDivScroll can be used. If you have cool examples of how you have used SmoothDivScroll, please drop me an email with the URL.

Back to table of contents

Parameters

Here are the parameters that can be supplied as arguments to the plugin. You can always leave all parameters out. Smooth Div Scroll will then use the default values.

ParameterDefault valueComment
scrollingHotSpotLeft:"div.scrollingHotSpotLeft"The identifier for the hotspot that triggers scrolling left.
scrollingHotSpotRight:"div.scrollingHotSpotRight"The identifier for the hotspot that triggers scrolling right.
scrollWrapper:"div.scrollWrapper"The identifier of the wrapper element that surrounds the scrollable area.
scrollableArea:"div.scrollableArea"The identifier of the actual element that is scrolled left or right.
hiddenOnStart:falseTrue or false. Determines whether the element should be visible or hidden on start. This can be useful if you combine Smooth Div Scroll with some other jQuery plugin that shows or hides areas, like an accordion.
ajaxContentURL:""Optional. If supplied, the content of scrollableArea is fetched via AJAX using the supplied URL.
countOnlyClass:""Optional. If supplied, the function that calculates the total width of the scrollable area will only count the width of the elements that have this class. This can be useful if you have content grouped in columns that should be made scrollable. Otherwise Smooth Div Scroll will sum up the total width of all the elements in the columns and in this case you only want the width of the actual columns.
scrollingSpeed:25A way of controlling the scrolling speed. 1=slowest and 100= fastest.
mouseDownSpeedBooster:1Use this if you want a speed boost when the user presses the mouse button while hovering over one of the hot spots.
1 = normal speed (no boost)
2 is twice as fast as normal
3 is three times as fast
and so on...
autoScroll:""Optional. Leave it blank if you don't want any autoscroll. Otherwise use the values "onstart" or "always". Using onstart the scrolling will start automatically after the page has loaded and scroll according to the method you've selected using the autoScrollDirection parameter. When the user moves the mouse over the left or right hot spot the autoscroll will stop. After that the scrolling will only be triggered by the hot spots. Using always - the hot spots are disabled alltogether and the scrollable area will only scroll automatically.
autoScrollDirection"right"Optional. This parameter controls the direction and behavior of the autoscrolling and is only used if autoscrolling is activated. Using right Smooth Div Scroll autoscrolls right and stops when it reaches the end. Using left it will autoscroll left and stop when it reaches the end (only relevant if you have set the parameter startAtElementId). If you set the value to backandforth Smooth Div Scroll starts autoscrolling right and when it reaches the end, switches to autoscrolling left and so on. Ping-pong style. Last but not least, setting the parameter to endlessloop will give you continuous scrolling right. An endless loop of elements.
autoScrollSpeed:1If autoScrollOnStart is set to true, this parameter sets the speed of the auto scrolling.
1-2 = slow
3-4 = medium
5-13 = fast
anything higher = superfast!
pauseAutoScroll""Optional. Possible values are mousedown and mouseover. Leave blank for no pausing abilities. If you choose mousedown autoscrolling will pause as long as the user holds down the mouse button while the pointer is over the scroller. If you choose mouseover, the user only needs to move the pointer over the scroller to pause the autoscrolling. When the pointer exits the scroller, autoscrolling will continue.
visibleHotSpots:""Optional. Leave it blank for invisible hot spots. Otherwise use the values "onstart" or "always". Onstart makes the hot spots visible for X-number of seconds (controlled via hotSpotsVisibleTime) after tha page has loaded and then they become invisible. Always is for making them visible all the time. Feel free to alter the graphics and CSS for the visible hot spots.
hotSpotsVisibleTime:5Optional. If you have set "onstart" as the value for the parameter visibleHotSpots, you set the number of seconds that you want the hot spots to be visible. After this time they will become invisible again.
startAtElementId:""Optional. Use this parameter if you want the offset of the scrollable area to be positioned at a specific element directly after the page has loaded. First give your element an ID in the HTML code and then provide this ID as a parameter.
Back to table of contents

The CSS

There is a CSS that accompanies the Smooth Div Scroll jQuery plugin. It looks like this:


/*	Invisible left hotspot */
div.scrollingHotSpotLeft
{
	/* 	The hotspots have a minimum width of 100 pixels 
	and if there is room the will grow and occupy 15% 
	of the scrollable area (30% combined). Adjust it 
	to your own taste. */
	min-width: 75px;
	width: 10%;
	height: 100%;
	/*	There is a big background image and it's used 
		to solve some problems I experienced
		with Internet Explorer 6. */
	background-image: url(../images/big_transparent.gif);
	background-repeat: repeat;
	background-position: center center;
	position: absolute;
	z-index: 200;
	left: 0;
	/*  The first url is for Firefox and other browsers, the second is for Internet Explorer */
	cursor: url(../images/cursors/cursor_arrow_left.cur), url(images/cursors/cursor_arrow_left.cur),w-resize;
}

/*	Visible left hotspot */
div.scrollingHotSpotLeftVisible
{
	background-image: url(../images/arrow_left.gif);				
	background-color: #fff;
	background-repeat: no-repeat;
	opacity: 0.35; /* Standard CSS3 opacity setting */
	-moz-opacity: 0.35; /* Opacity for really old versions of Mozilla Firefox (0.9 or older) */
	filter: alpha(opacity = 35); /* Opacity for Internet Explorer. */
	zoom: 1; /* Trigger "hasLayout" in Internet Explorer 6 or older versions */
}

/* Invisible right hotspot */
div.scrollingHotSpotRight
{
	min-width: 75px;
	width: 10%;
	height: 100%;
	background-image: url(../images/big_transparent.gif);
	background-repeat: repeat;
	background-position: center center;
	position: absolute;
	z-index: 200;
	right: 0;
	/*  The first url is for Firefox and other browsers, the second is for Internet Explorer */
	cursor: url(../images/cursors/cursor_arrow_right.cur), url(images/cursors/cursor_arrow_right.cur),e-resize;
}

/* Visible right hotspot */
div.scrollingHotSpotRightVisible
{
	background-image: url(../images/arrow_right.gif);
	background-color: #fff;
	background-repeat: no-repeat;
	opacity: 0.35;
	filter: alpha(opacity = 35);
	-moz-opacity: 0.35;
	zoom: 1;
}

/*	The scroll wrapper is always the same width and 
	height as the containing element (div). Overflow 
	is hidden because you don't want to show all of 
	the scrollable area.
*/
div.scrollWrapper
{
	position: relative;
	overflow: hidden;
	width: 100%;
	height: 100%;
}

div.scrollableArea
{
	position: relative;
	width: auto;
	height: 100%;
}
Back to table of contents

Dependencies

Smooth Div Scroll depends heavily on the hard work of another plugin developer so you can't run it unless you have the jquery.scrollTo plugin.

Also you will need the latest version of jQuery. In this example I'm using 1.3.2.

Back to table of contents

Download

Download a zip-file with the latest javascript (full commented source code + a minified version), CSS, cursors and some images. You will also need to download the jquery.scrollTo plugin. Otherwise it will not work.

winzip iconDownload SmoothDivScroll_0-9.zip

Back to table of contents

Help and support

I receive a lot of emails from people all over the World, asking me questions about Smooth Div Scroll. I really appreciate getting mail but working full time and being a father of two, I simply don't have the time to provide support and help everyone with site-specific questions. Therefore I have created a Google group where users can help each other.

Google Groups
Subscribe to jQuery SmoothDivScroll
Email:
Visit this group

Please turn to this group for help and support.

Back to table of contents

Newsletter

I send an email to all my smooth scrolling friends whenever there's a new version of Smooth Div Scroll. Sign up if you want to know when there's a new version. I promise I won't spam you with lot's of stuff - just useful info and not very often.

Subscribe to the Smooth Div Scroll Newsletter

Back to table of contents

FAQ

If you have any questions, please turn to the jQuery SmoothDivScroll Google group.

Combining Smooth Div Scroll and pop up/display scripts like Fancybox? Question from David: Your Logo scroller is kick ass. I have been looking for something like it for sometime. My boss saw it yesterday and asked, "Can you make it popup like the images do with Fancybox?" I managed to get it working... mostly. I took what you had done, and wrapped the images with the Fancybox call. It works on the first run of the images, but when the images do their second and third and so on runs the Fancybox no longer works. Is there an easy fix?
Answer: Hi David!

I think I know what's causing this. The fact that it only works the first time around in the loop suggests that the linking to the Fancybox script is lost forever once an element in the slider slides out of view.

Smooth Div Scroll (when set to loop endlessly) works like this:
  1. It clones the element that has just slided out of view.
  2. It takes the cloned element and puts it last in the parading queue of elements.
  3. It deletes the original element that just slided out of view.
So what I think happens is that the elements that Fancybox has identified as "its elements" (the elements that it has attached the Fancybox behavior on) no longer exists - the binding of event is lost in the process when Smooth Div Scroll keeps cloning and deleting elements.

The solution is to use the jQuery live-event in this way:

<script type="text/javascript">
  $(document).ready(function(){
   
    $("a").live("mouseover", function(){
      $(this).fancybox();
    });

  });
  </script>
Special thanks to Brent Hackman for sharing this solution!
Flickering issue when using autoscrolling in IE7. Question from Alex: I’m having a flickering issue in IE7 (maybe other versions as well but I haven’t tested yet). You can see it on your endless loop demo. It slides fine but then seems to jump (to its initial state, perhaps?) for a millisecond then jumps back right where it left off and keeps going. This isn’t a problem in any other browser as far as I can tell. Have you encountered this before? Any help would be greatly appreciated.
Answer: Hi Alex!

This is something I’m aware of and I have made some progress in solving it, but I’m not completely finished yet. The jumping has to do with a problem in the endless looping function. The function works by moving and removing elements from the DOM in an endless queue and in IE7 this is not working 100%. There are differences in how browsers interpret CSS and execute JavaScript (performance). If you look at the same example in Firefox there will be no jumping. Looking at the same page in Google Chrome you’ll see that the scrolling is somewhat faster due to Chrome’s super fast JavaScript engine. And so on. Usually scrollers like these are made using Flash which is a much more controlled environment. When doing the same thing in JavaScript it’s a feat to take all user-specific cases and all different browser environments into account. Still, it’s my goal to get a smooth experience regardless of browser.

There will be a version 0.9 coming sometime this summer, but I’m not releasing it yet since I haven’t had time to do enough testing. When version 0.9 is released it will be announced in my newsletter.
Scrollbar? Question from Vincent: I like your jQuery scrolling plugin and was wondering if you have an example with a scroll bar instead of left and right buttons to do scrolling? I think the scroll bar would be a nice addition to the plugin if it doesnt already have it which I dont think it does from what I saw so far. Thanks for the nice work!
Answer: Hi Vincent!

I don’t think I will add scrollbars to Smooth Div Scroll in the near future since I have several other requests with higher priority on my to-do list. Also, there are other plugins that do exactly this, for example jScrollHorizontalPane. Good luck with the scrolling and I hope you get the solution you are looking for!
Vertical scrolling? Question from Cristina: My name is Cristina and I come from Italy, I've just seen you Smooth Div Scroll, and I've found it fantastic! I wonder if there is a parameter to scroll up and down?
Answer: Ciao Cristina!

Sorry, there's no parameter for scrolling up and down. I've had many requests for that feature though so perhaps I will start working on a version that scrolls vertically instead of horizontally, but that will be sometime in the future.
Slower speed? Question from Jean-Michel: Do you think there would be a way to implement a slower scrolling speed than 1?
Answer: Salut Jean-Michel!

I’m currently working on this, but I haven’t found the perfect solution yet. There is a fundamental problem with scrolling using JavaScript and that is the fact that the smallest step you can move something is one pixel. In Flash, you can actually scroll in steps smaller than one pixel due to the fact that Flash uses anti-aliasing in a clever way. So, in JavaScript, if you have set the movement distance to one pixel and still want to go slower, the only way is to increase the time between each movement. This is done by altering the interval. The problem is that if you increase the time between each movement there is a risk that it will look "jumpy" - not smooth.

There is also a difference between how fast different browsers can run the code (JavaScript performance). You'll find the poorest performance in Internet Explorer 7. Firefox works fine. Google Chrome is blindingly fast when it comes to executing JavaScript.
Back to table of contents

Version history

VersionComments
0.9Bugfixes. Problem with multiple autoscrollers on the same page - the intervals where global which resulted in the wrong autoscroller stopping on mouseOver or mouseDown. Error in calculation in autoscrolling mode that made the autoscrolling grind to a halt after a number of loops.
0.8Major update. New parameter setup. Lots of new autoscrolling capabilities and new parameters for controlling the scrolling speed. Made it possible to start the scroller at a specific element.
0.7Some small additions. Added support for autoscrolling after the page has loaded.
Added support for making the hot spots visible at start for X number of seconds or visible all the time.
0.6The first official release.
Back to table of contents

To-do (the next version)

Altering the cloning action when scrolling in an endless loop. The problem is that the new cloned elements don't get their events bound as they're cloned. You can use .live as a fix for this, but as Paul Shapiro kindly pointed out, a simpler solution is to use clone(true). This way it will also clone the event handlers bound to the elements.

Martin Schubert reported problems when replacing the content of the scrollable area using AJAX after the page had loaded - Smooth Div Scroll doesn't recalculate the scrollable area. The recalculation is done first when the user resizes the browser window. Looking at the source code there's a function called "windowIsResized". This is triggered when the user resizes the browser window and it (among other things) properly recalculates the width of the scrollable area. The code should be rewritten with a general function that "reinitializes" the scroller. This function should be a part of the public API so it can be called by the developer after an AJAX content load has been done.

Vincent Weber wrote me regarding the cursors and the fact that the custum cursors are not shown in Internet Explorer. The problem has to do with relative URL's. The URL that is relative to the CSS is used by Firefox and other browsers and looks like this:


// Firefox cursor URL
cursor: url(../images/cursors/cursor_arrow_right.cur), w-resize;

Internet Explorer on the other hand wants you to use the HTML sourse file as the base of the URL, not the CSS. An example of an Internet Explorer URL would be:


// Internet Explorer cursor URL
cursor: url(images/cursors/cursor_arrow_right.cur), w-resize;

If you want it to work in both Internet Explorer, Firefox and other browsers you simply supply both URL's, like this:


// Cursor URL for both Internet Explorer and other browsers
cursor: url(../images/cursors/cursor_arrow_right.cur), url(images/cursors/cursor_arrow_right.cur),w-resize;

Vincent also sent a reference regarding custom cursors for anyone who wants to read more. This cursor CSS is implemented in the demo on this page.

Konstantin Hidirov found a solution to the problem with setting slower scrolling speeds and was kind and sent me an email with his example. A solution along his lines will be implemented in the next version, but for those of you who want to fix it right now, here's an example:

1) Place this code at the beginning of plugin file


window.splitterValue = 1;

function splitter(cnt) {
  window.splitterValue++;
  var r = (window.splitterValue > cnt);
  if (r) window.splitterValue = 1;
  return r;
}

This function returns TRUE in 1/cnt cases.

2) Then, put the next line into the main routine. I used "backandforth" mode and placed it so:


....
case "backandforth":
    if (!splitter(3)) return;
....

Now the speed of animation will be 1/3. As Konstantin points out, the code might need some cleaning and it needs to be properly tested and integrated into the plugin, but this will do for now.

Back to table of contents

Copyright, license and all that

Copyright © 2010 Thomas Kahn - thomas(at)karnhuset(dot)net

This plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.

This plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

Back to table of contents

About me

My name is Thomas Kahn and I live and work in Stockholm, Sweden. I've been working as a web developer for the past thirteen years. Currently I'm working at a small advertising agency called Kärnhuset in central Stockholm. When I'm not dabbling with jQuery I program in ASP.NET/C#, XML/XSLT and I also do a lot of XHTML/CSS. Umbraco is my favorite CMS and I try to be as active as I can in the Umbraco community.

Please email suggestions on improvements! This is the first jQuery plugin that I've developed so there must be quite a lot that can be improved: thomas(at)karnhuset(dot)net.

Happy scrolling!

Back to table of contents

Do you want to help out or give this plugin a rating?

If you found this plugin useful, I would really appreciate it if you could give it a nice rating on my jQuery plugin page. That way more people will find it and use it, which is my goal with this project. On the top of the jQuery plugins page you'll find a star rating widget that enables you to give the plugin a rating. You need to be logged in.

If you are an experienced jQuery plugin developer and want to contribute to make this plugin the best smooth scrolling plugin ever, don't hesitate to drop me an email: thomas(at)karnhuset.net! .

Back to table of contents