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
- How it works
- Quick demo
- Key features
- More examples!
- Parameters
- The CSS
- Dependencies
- Download
- Help and support
- Newsletter
- FAQ
- Version history
- To-do (the next version)
- Copyright, license and all that
- About me
- 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.
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:
- onstart - initial autoscroll until the user interacts with the scroller by moving the pointer over one of the hot spots. After that all scrolling has to be done using the hot spots.
- always - no user interaction (hot spots are disabled) and the scrolling is controlled only by the parameters you've set for autoscrolling.
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:
- right - autoscrolls right and stops when it reaches the end.
- left - autoscrolls left and stops when it reaches the end. (Setting the autoScrollDirection to "left" is only relevant if you use the parameter startAtElementId and set it to something other than the first element.)
- backandforth - starts autoscrolling right and when it reaches the end, switches to autoscrolling left and so on. Scrolling ping-pong style.
- endlessloop - continuous scrolling right - an endless loop of elements. When the scroller reaches the last element the first will appear and so on in a never-ending loop.
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 contentsQuick 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:
- A somewhat slower scrolling speed than the default speed (scrollingSpeed: 12).
- A speed boost so the scrolling will go three times as fast if the user presses the mouse button while inside one of the scrolling hot spots (mouseDownSpeedBooster: 3).
- Set the autoscrolling to "onstart" (autoScroll: "onstart") so I get autoscrolling until the user uses one of the hot spots.
- I want the autoscrolling to be an endless loop (autoScrollDirection: "endlessloop").
- Custom autoscrolling speed (autoScrollSpeed: 2).
- Set the parameter for making the hot spots visible on start and a custom number of seconds that I want them to be visible (visibleHotSpots: "onstart" and hotSpotsVisibleTime: 9). This means the hot spots will be visible for 9 seconds after the page has loaded and then disappear. (If you don't see them, it's probably because they have disappeared before you got down to this section of the page.)
- Set the parameter for starting at a specific element inside the scrollable area. In this case I've given the element that I want to start at the id "startAtMe".
The result is this:
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 contentsKey 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:
- Scrolling hot spots that are activated and deactivated depending on if they are needed or not. For example, if you have scrolled as far to the right as possible, scrollingHotSpotRight becomes inactive (hidden) and vice versa with scrollingHotSpotLeft. Another example: if the width of scrollableArea is equal to or shorter than scrollWrapper, both scrolling hot spots become inactive - obviously.
- The scrolling speed varies depending how far left or right you move the mouse pointer inside the hot spot.
- You should be able to put any element into the scrollable area as long as its width and height can be calcuated since Smooth Div Scroll does a lot of calculations using the width and height of the elements inside it. If you are experiencing problems with this you can try wrapping your elements in div's or set the element display to block in the CSS.
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.
- Scrolling text
- Small scroller
- Running ticker
- Clickable logo parade
- Ping-pong scroller
- Multiple autoscrollers on one page (loading content through AJAX)
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.
| Parameter | Default value | Comment |
|---|---|---|
| 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: | false | True 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: | 25 | A way of controlling the scrolling speed. 1=slowest and 100= fastest. |
| mouseDownSpeedBooster: | 1 | Use 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: | 1 | If 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: | 5 | Optional. 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. |
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 contentsDownload
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.
Download SmoothDivScroll_0-9.zip
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.
|
|
| Subscribe to jQuery SmoothDivScroll |
| Visit this group |
Please turn to this group for help and support.
Back to table of contentsNewsletter
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.
Back to table of contentsFAQ
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:
The solution is to use the jQuery live-event in this way:
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. |
Version history
| Version | Comments |
|---|---|
| 0.9 | Bugfixes. 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.8 | Major 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.7 | Some 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.6 | The first official release. |
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 contentsCopyright, 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 contentsAbout 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 contentsDo 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