Need some help?

I'm usually available for small jobs or problem solving with jQuery or css, at reasonable rates. Just get in touch.

Web Hosting

We recommend Clook for web hosting. UK based, great service and great value.

Buy me a drink

If you've found this useful, particularly for commercial projects, you might consider making a small donation.

Vertical scrollbar using jQuery UI slider

Also available as a jQuery plugin.

Here’s my attempt at using jQuery UI Slider as a vertical scrollbar. I began this in 2010 by adapting the code on the jQuery UI site for a horizontal slider. This worked, but seemed unnecessarily complex, so I had another go, starting from the vertical slider code. Since then I’ve had numerous requests for different variations on the basic scrollbar, and these are all now incorporated into a single piece of code.

The code assumes a div with fixed height (#scroll-pane or .scroll-pane in my examples) which contains the content for scrolling. The script wraps the contents of the div to be scrolled in another div (.scroll-content) which is used positioned absolutely, and then the top value of #scroll-content is changed via the slider to make the content scroll up and down. The scrollbar itself is positioned within #scroll-pane, using absolute positioning on the right hand side, but it can go anywhere you like.

There’s a fundamental aspect of the way the vertical slider works which took me a little time to get my head round, and that’s that the slider as a default starts from zero at the bottom and increases upwards – which is the wrong way round for a vertical scroller, hence the need for a bit of extra calculation.

So, here’s the css:

#scroll-pane,.scroll-pane{position:relative}
.scroll-content {position:absolute;top:0;left:0}
.slider-wrap{position:absolute;right:0;top:0;background-color:lightgrey;width:20px;border-left:1px solid gray;}
.slider-vertical{position:relative;height:100%}
.ui-slider-handle{width:20px;height:10px;margin:0 auto;background-color:darkgray;display:block;position:absolute}
.ui-slider-handle img{border:none}
.scrollbar-top{position:absolute;top:0;}
.scrollbar-bottom{position:absolute;bottom:0;}
.scrollbar-grip{position:absolute;top:50%;margin-top:-6px;}
.ui-slider-range{position:absolute;width:100%;background-color:lightgrey}

and here’s the javascript. For convenience I’ve wrapped all the code needed for all the different variations below into one function called setSlider().

function setSlider($scrollpane){//$scrollpane is the div to be scrolled
	
	//set options for handle image - amend this to true or false as required
	var handleImage = false;
	
	//change the main div to overflow-hidden as we can use the slider now
	$scrollpane.css('overflow','hidden');
	
	//if it's not already there, wrap an extra div around the scrollpane so we can use the mousewheel later
	if ($scrollpane.parent('.scroll-container').length==0) $scrollpane.wrap('<\div class="scroll-container"> /');
	//and again, if it's not there, wrap a div around the contents of the scrollpane to allow the scrolling
	if ($scrollpane.find('.scroll-content').length==0) $scrollpane.children().wrapAll('<\div class="scroll-content"> /');
	
	//compare the height of the scroll content to the scroll pane to see if we need a scrollbar
	var difference = $scrollpane.find('.scroll-content').height()-$scrollpane.height();//eg it's 200px longer 
	$scrollpane.data('difference',difference); 
	
	if(difference<=0 && $scrollpane.find('.slider-wrap').length>0)//scrollbar exists but is no longer required
	{
		$scrollpane.find('.slider-wrap').remove();//remove the scrollbar
		$scrollpane.find('.scroll-content').css({top:0});//and reset the top position
	}
	
	if(difference>0)//if the scrollbar is needed, set it up...
	{
		var proportion = difference / $scrollpane.find('.scroll-content').height();//eg 200px/500px
		
		var handleHeight = Math.round((1-proportion)*$scrollpane.height());//set the proportional height - round it to make sure everything adds up correctly later on
		handleHeight -= handleHeight%2; 
		
		//if the slider has already been set up and this function is called again, we may need to set the position of the slider handle
		var contentposition = $scrollpane.find('.scroll-content').position();	
		var sliderInitial = 100*(1-Math.abs(contentposition.top)/difference);
		
		if($scrollpane.find('.slider-wrap').length==0)//if the slider-wrap doesn't exist, insert it and set the initial value
		{
			$scrollpane.append('<\div class="slider-wrap"><\div class="slider-vertical"><\/div><\/div>');//append the necessary divs so they're only there if needed
                        sliderInitial = 100;
		}
		
		$scrollpane.find('.slider-wrap').height($scrollpane.height());//set the height of the slider bar to that of the scroll pane
		
		//set up the slider 
		$scrollpane.find('.slider-vertical').slider({
			orientation: 'vertical',
			min: 0,
			max: 100,
			range:'min',
			value: sliderInitial,
			slide: function(event, ui) {
				var topValue = -((100-ui.value)*difference/100);
				$scrollpane.find('.scroll-content').css({top:topValue});//move the top up (negative value) by the percentage the slider has been moved times the difference in height
				$('ui-slider-range').height(ui.value+'%');//set the height of the range element
			},
			change: function(event, ui) {
				var topValue = -((100-ui.value)*($scrollpane.find('.scroll-content').height()-$scrollpane.height())/100);//recalculate the difference on change
				$scrollpane.find('.scroll-content').css({top:topValue});//move the top up (negative value) by the percentage the slider has been moved times the difference in height
				$('ui-slider-range').height(ui.value+'%');
		  }	  
		});
		
		//set the handle height and bottom margin so the middle of the handle is in line with the slider
		$scrollpane.find(".ui-slider-handle").css({height:handleHeight,'margin-bottom':-0.5*handleHeight});
		var origSliderHeight = $scrollpane.height();//read the original slider height
		var sliderHeight = origSliderHeight - handleHeight ;//the height through which the handle can move needs to be the original height minus the handle height
		var sliderMargin =  (origSliderHeight - sliderHeight)*0.5;//so the slider needs to have both top and bottom margins equal to half the difference
		$scrollpane.find(".ui-slider").css({height:sliderHeight,'margin-top':sliderMargin});//set the slider height and margins
		$scrollpane.find(".ui-slider-range").css({bottom:-sliderMargin});//position the slider-range div at the top of the slider container
		
		//if required create elements to hold the images for the scrollbar handle
		if (handleImage){
			$(".ui-slider-handle").append('');
			$(".ui-slider-handle").append('');
			$(".ui-slider-handle").append('');
		}
	}//end if
		 
	//code for clicks on the scrollbar outside the slider
	$(".ui-slider").click(function(event){//stop any clicks on the slider propagating through to the code below
		event.stopPropagation();
	});
	   
	$(".slider-wrap").click(function(event){//clicks on the wrap outside the slider range
		var offsetTop = $(this).offset().top;//read the offset of the scroll pane
		var clickValue = (event.pageY-offsetTop)*100/$(this).height();//find the click point, subtract the offset, and calculate percentage of the slider clicked
		$(this).find(".slider-vertical").slider("value", 100-clickValue);//set the new value of the slider
	}); 
	
		 
	//additional code for mousewheel
	if($.fn.mousewheel){		
	
		$scrollpane.parent().unmousewheel();//remove any previously attached mousewheel events
		$scrollpane.parent().mousewheel(function(event, delta){
			
			var speed = Math.round(5000/$scrollpane.data('difference'));
			if (speed <1) speed = 1;
			if (speed >100) speed = 100;
	
			var sliderVal = $(this).find(".slider-vertical").slider("value");//read current value of the slider
			
			sliderVal += (delta*speed);//increment the current value
	 
			$(this).find(".slider-vertical").slider("value", sliderVal);//and set the new value of the slider
			
			event.preventDefault();//stop any default behaviour
		});
		
	}
	
}

I’ve tested this on: IE6, IE7, IE8, FF3.6, Safari 4, Chrome and Opera9/10/11 on Win/XP; IE8, IE9, FF9/10, Opera 11, Safari 5 and Chrome on W7; FF7, Epiphany and Chromium on Ubuntu; and Safari 5 on Mac OS X/Snow Leopard. See the demos below for various applications and uses.

Can I use this on my site?

Probably. See my policies on using code from this site.

Please don’t link directly to the javascript on my site. Due to the number of hits on my bandwidth because people were doing this I’ve had to deny direct access to javascript files. Use a CDN like Google’s instead.

Touch screens: As it stands, this will not work with touch screens as jQuery UI does not itself support touch events. I have done only limited testing, but TouchPunch seems to work on an iPad and iPhone, but not on earlier Android devices. See here for some limited testing results – please let me know of anything you have to add to this.

Help! It doesn’t work

If you hit problems, start off by looking at my beginners’ guide to debugging jquery. Most of the problems encountered by users are listed here.

Demos

Basic scrollbar: Demo

setSlider($('#myElement'));

Multiple scrollbars: Demo

$('.myElementClass').each(function(){
	setSlider($(this));
});

Originally added after these two questions within days of each other.

Changing the contents after load: add or remove content within the scrolled element Demo

setSlider($('#myElement'));

function changeContent{//do whatever you want....
...code to change content....
setSlider($('#myElement'));//call the function again to reset the slider for the new content
}

Originally in response to this comment, the slider code will check for the existence of a slider, remove it if it’s no longer required (or establish it if it’s newly required), and aslso set the slider position to match any previous scroll point.

Scrollbar resizes with window: Demo

setSlider($('#myElement'));

$(window).resize(function() {
	setSlider($('#myElement'));
});

originally in response to Igor’s comment, this supports a percentage height .scroll-pane and resizes with the viewport resize. Again, the solution is to call setSlider() on a window resize event.

Scrollbar on a div that’s originally hidden Demo

$('#myElement').show();//or whatever you want, then...
setSlider($('#myElement'));//...call the function again to reset the slider for the new content
}
});

When the div is originally hidden – for example via display:none, most browsers will read it as having zero height and hence all the caslculations decide that a scrollbar isn’t needed. The solution to this just to call setSlider() (again) when the hidden div is displayed.

Preset the scroll position on load: Demo

setSlider($('#myElement'));

//code to set an initial scrolled position
var position = $("#targetElement").position();//find the position of the required item
var topValue = position.top;//extract the top value
var sliderValue = 100-(100*topValue/($(".scroll-content").height()-$("#scroll-pane").height()));//calculate the percentage of the top of the required item
$(".slider-vertical").slider("value", sliderValue);//and set the new value of the slider

Autocomplete: scroll to an item selected from a database Demo Fuller explanation

setSlider($('#myElement'));
//autocomplete
var difference = $(".scroll-content").height()-$("myElement").height(); 
$("#quickfind").autocomplete({
	source: "get_descriptions.php",
	minLength: 2,//search after two characters
	select: function(event,ui){
		position = $(".scroll-content-item:contains("+ui.item.value+")").position();//search for a div containing the selected description and read its position
		
		var topValue = -(position.top);//content top is just the negative of the top position
		
		if (topValue>0) topValue = 0;//stop the content scrolling down too much
		if (Math.abs(topValue)>difference) topValue = (-1)*difference;//stop the content scrolling up too much
	
		sliderVal = (100+(topValue*100/difference));//calculate the slider position from the content position
		$(".slider-vertical").slider("value", sliderVal);//set the slider position
		}
});

Originally in response to Dan’s comment.

Scroll automatically on load: have the element scrolling without user input Demo

setSlider($('#myElement'));

var scrollId = setInterval('scrollDown()', 60);// start the autoscroll via a function

$(".ui-slider-handle").mouseover(function(){//stop the autoscroll if the handle is hovered
    clearInterval(scrollId);
});

function scrollDown(){
	if ($(".slider-vertical").slider("value")>0){//if it's not at the bottom, scroll down
		$(".slider-vertical").slider("value",$(".slider-vertical").slider("value")-1);
	}
}

Originally in response to this comment. Can’t quite see the application of this one either…

Scrolling with buttons: Demo

setSlider($('#myElement'));

$('#arrow_up').mousedown(function(event) {
	if(event.preventDefault) event.preventDefault();
    intervalId = setInterval('scrollUp()', 30);
	$(this).bind('mouseup mouseleave', function() {
		clearInterval(intervalId);
	});
});
$('#arrow_down').mousedown(function(event) {
	if(event.preventDefault) event.preventDefault();
    intervalId = setInterval('scrollDown()', 30);
	$(this).bind('mouseup mouseleave', function() {
		clearInterval(intervalId);
	});
});

function scrollUp(){
	if ($(".slider-vertical").slider("value")<100){//if it's not at the top, scroll up
		$(".slider-vertical").slider("value",$(".slider-vertical").slider("value")+1);
	}
}
function scrollDown(){
	if ($(".slider-vertical").slider("value")>0){//if it's not at the bottom, scroll down
		$(".slider-vertical").slider("value",$(".slider-vertical").slider("value")-1);
	}
}

#arrow_up and #arrow_down are the ids for the arrow buttons, although you’d probably guessed that…Originally in response to this comment. Dick pointed out that if you try and drag the scrolling buttons it can occasionally cause the scroller to break. I couldn’t recreate this at all, but added some code to prevent the buttons being dragged, which Dick confirms fixes the problem.

Scrolling to anchors: Demo

setSlider($('#scroll-pane'));

$('#anchors a').click(function(){

	var difference = $('.scroll-content').height()-$('#scroll-pane').height();//calculate the difference - not needed if within the main slider code
	
	var targetclass = ($(this).attr('class'));//read the class of the clicked anchor
    
	var position = $(".scroll-content ."+targetclass).position();//search for a div with matching class and read its position
    var topValue = -(position.top);//content top is just the negative of the top position
		
	if (topValue>0) topValue = 0;//stop the content scrolling down too much
	if (Math.abs(topValue)>difference) topValue = (-1)*difference;//stop the content scrolling up too much

	sliderVal = (100+(topValue*100/difference));//calculate the slider position from the content position
	$(".slider-vertical").slider("value", sliderVal);//set the slider position
	
	return false;
});

This assumes markup where the anchors are assigned a class which is also added to the ‘target’ scroll point within the div. View source for the details.

Easing: animate the slider using easing Demo

Had a couple of comments asking about easing. It doesn’t work well with the code as it is, because the bar scrolls at every mouse move. However, if the slider code is changed to call the animation on the change event instead of the slide event, then it is possible, although the scrolled content will not move until the slider is stopped. I don’t care for this one at all, although it does work better with anchors.

Note that this (the only demo that) uses a different version of setSlider(), where the slider is instantiated via:.

   //set up the slider 
   $scrollpane.find('.slider-vertical').slider({
      orientation: 'vertical',
      min: 0,
      max: 100,
	  range:'min',
      value: sliderInitial,
      change: function(event, ui) {
			 var topValue = -((100-ui.value)*difference/100);
			 $scrollpane.find('.scroll-content').[highlight]animate({top:topValue},animateSpeed,easingMethod[/highlight]);//move the top up (negative value) by the percentage the slider has been moved times the difference in height
			 $('ui-slider-range').height(ui.value+'%');
	  }	  
   });

You need to set the variables animateSpeed and easingMethod, of course, and include the easing plugin.

Shopping cart: with jQuery UI draggable/droppable Demo

setSlider($('#myElement'));
$('.item').draggable({appendTo:'body',helper:'clone'});
$('#droppable').droppable({
	drop:function(event,ui){
		$( this ).find( "#placeholder" ).remove();
		var description = ui.draggable.find('p').text();
		$( "<\li><\/li>" ).text(description).appendTo( $('#droppable ul') );
	}
});

originally in response to Juan’s comment, minimal droppable code to to allow dragging from the scrolling div and dropping into a basket.

Autohide scrollbar: so it’s displayed only on hover Demo

setSlider($('#myElement'));
$(".slider-wrap").hide();
$("#myElement").hover(function(){
	$(".slider-wrap").show();
	},
	function(){
	$(".slider-wrap").hide();
});

Robert asked about an autohide function. I really don’t like it…

Styling the handle Demo

setSlider($('#myElement'));

plus these settings within setSlider():

function setSlider($scrollpane){//$scrollpane is the div to be scrolled
	
	//set options for handle image - amend this to true or false as required
	var handleImage = [highlight]true[/highlight];
         
        ...

	if (handleImage){//change the image paths as required for your images - delete any that are not required if you want
		$(".ui-slider-handle").append('');			
                $(".ui-slider-handle").append('');
		$(".ui-slider-handle").append('');
	}

        ...

and this addtional css

.ui-slider-handle{background:transparent url(/images/misc/scrollbar-handle-middle.png) repeat-y top left;}

In order to make this example bulletproof, I’ve used four images (!) – one each for the top and bottom of the handle, one for the white ‘grip’ in the middle, and one for the rest set via the css. Although this feels a bit over the top it works for a scrollbar of any length. In order to do this the code optionally appends three images into the scrollbar handle html after instantiating the slider.

Styling the scrollbar Demo

This is just an additional piece of css:

.slider-wrap{background-color:#EA9531;}

Originally in response to this question this allows one side of the scrollbar to extend – easier to view than describe.The slider already adds an extra element .ui-slider-range which in the standard css is coloured the same as the scrollbar background – so it’s just a question of changing one of these. IE6 does odd things during the scroll though, which I can’t fix, suggestions welcome.

Changelog

6 March 2012 – consolidated all variations to use standard code

Mostly in order to make keeping these things up to date a bit easier, I’ve consolidated all the different variants to use a single version of code, which supports everything. There’s no real change to the mechanics of the slider, just how it’s packaged up. Also tidied up two bits of ancillary code, specifically on the scrolling with buttons example.

28 February 2012 – upgrade to jQuery/UI/mousewheel

I’ve upgraded all the demos to use jQuery 1.7.1, jQuery UI 1.8.14 and Mousewheel 3.0.6. At the same time I’ve wrapped the mousewheel code in a conditional to stop any errors if the mousewheel plugin is not loaded, and amended the mousewheel code so that it copes better with variances in the scrolled content – the previous code resulted in a 5% vertical shift on a mousewheel rotate – this now varies dependent on the difference in size between the scrolling element and its content.

10 January 2012 – tweaks to mousewheel code

I’ve amended the mousewheel code in three examples where the slider set up may be called more than once, as previously repeated calling of the code resulted in very fast mousewheel scrolling. Examples affected are Add Content, Window Resize and Hidden Divs.

9 November 2011 – packaged as a plugin

Finally packaged this up as a plugin.

1 March 2011 – improved handling of clicks outside handle and mousewheel

In the process of sorting out the Opera issues below, I’ve made a couple of improvements. Previously, clicks beyond the handle, and beyond the actual slider (which is less high than #slider-wrap to accommodate the handle) weren’t handled very well, and didn’t work in IE. They do now, by looking at the point at which the click was made and moving the slider appropriately. This replaces the changes made 16 January 2011. I’ve also simplified the mousewheel code to move #scroll-content from the slider by using the change option – see the code above, which replaces original code added 4 August 2010. These changes are now applied to all the demos.

27 February 2011 – amendments for Opera 11 issues

Following a contact from a user reporting difficulties with Opera 11 when resizing the scroll content, I have amended the demos for both this and for the multiple slider. Opera 11 doesn’t like the scrollbar being absolutely positioned, it seems, so all demos are now updated to position the scrollbar differently. This doesn’t significantly affect the javascript. This wasn’t an issue with Opera 9 or Opera 10. Makes a change from IE messing things up I suppose…

16 January 2011 – handle clicks at top and bottom of the scrollbar correctly

Ohm-ish points out that clicks on the top and bottom of the scrollbar, outside the handle, do not result in a scroll. This is because the slider range is restricted to less than the total height of the scrollbar to allow the handle to fit in.

Attempts to use the whole height of the slider work, but then the scrollbar handles doesn’t track the mouse correctly. Experimentation shows that adding .ui-slider-range sorts clicks above the slider range – this needs the following css:

.ui-slider-range{position:absolute;width:100%}

and I’ve then added a little jQuery to cope with clicks below the slider range:

//position the slider range div at the top of the slider wrap - this ensures clicks above the area through which the handle moves are OK
$(".ui-slider-range").css({top:-sliderMargin});

//add a click function to ensure clicks below the area through which the handle moves are OK
$("#slider-wrap").click(function(){//this means the bottom of the slider beyond the slider range is clicked, so move the slider right down
   $("#slider-vertical").slider("value", 0);
   $('#scroll-content').css({top:-difference});   
})

This has now been added to all the demos and the code shown above.

15 November 2010 – ensure the handle height margins are correct

Thanks to Thom for a suggested addition to ensure the handle height is exactly divisible by two. Without this, browsers other than FF show a 1px gap under the slider handle when it’s at the bottom of the slide.

8 November 2010 – allow for the scrollbar not being required

Following Jorge’s question below, I’ve amended the code slightly so that the slider is only added if it’s needed (if the height of #scroll-content is greater than the height of #scroll-pane), and as part of this added the necessary html for the scroller via jQuery. I’ve also added a line so the height of the scrollbar is set to the height of #scroll-pane.

8 September 2010 – mouse and scrollbar synced correctly

Following Rob’s comment (#5 below) I’ve amended both the css and javascript to fix a problem where the mouse and scrollbar weren’t in sync. Both the code on this page and the demo are updated.

4 August 2010 – mousewheel integration

Following Yves’ comment below I thought I’d have a go with adding mousewheel functionality as well. I used Brandon Aaron’s mousewheel plugin.

Then I’ve added the following additional javascript:

$("document").mousewheel(function(event, delta){

     var speed = 5;//set the speed of the scroll
     var sliderVal = $("#slider-vertical").slider("value");//read current value of the slider
		
     sliderVal += (delta*speed);//increment the current value
 
     $("#slider-vertical").slider("value", sliderVal);//and set the new value of the slider
		
     var topValue = -((100-sliderVal)*difference/100);//calculate the content top from the slider position
		
     if (topValue>0) topValue = 0;//stop the content scrolling down too much
     if (Math.abs(topValue)>difference) topValue = (-1)*difference;//stop the content scrolling up too much
		
     $("#scroll-content").css({top:topValue});//move the content to the new position

     event.preventDefault();//stop any default behaviour

});

I’ve kept this code separate from the rest so you can use it as required. It’s included in the demo page. The mousewheel works anywhere on the page on the demo – to restrict it to operate only on the scrolling div itself the opening statement would be amended to:

$("#scroll-pane,#slider-wrap").mousewheel(function(event, delta){...etc

Tags:

162 responses to “Vertical scrollbar using jQuery UI slider”

  1. henning fischer says:

    one word: awesome. tested so many scrollbar scripts and this is so simple and powerfull! thx a lot.

  2. Simon says:

    Yes, you could do this. Making the slider horizontal is just a simple change in the settings, and then you’d need to amend the javascript that scrolls the div to scroll the whole page instead. .scrollTop() might help you here. I think you’d want the slider to be position:fixed, not absolute, so it doesn’t scroll.

  3. Champo says:

    Hi Simon,

    Thank you very much for this.

    Is it possible to have the scrollbar to be horizontal and as a seperate div (ideally position:absolute; bottom: 20px;) ?

    I need to control the vertical scroll of the entire page (height: 5000px). By scrolling down the page i activate a background png sequence. I want to control this with the horizontal slider/scrollbar.

    I don’t know if i am clear enough. In simple i want a slider that when clicked left to right, makes you go from page top to page bottom.

    Thank you

    Eliott

  4. Simon says:

    You’d need to call setSlider() again after adding the content.

  5. Madhu Sudan .K says:

    Hi Simon,
    Really wonderful work, demos and examples. Thank you so much.
    I have a small query – if I add some content through Firefox console(edit) then the content is not shown by the div with the vertical scroll.
    Is it possible to make div know the content height when the content was given from a browser.
    The default scroller adjusts itself when it is done from Firefox page.
    Thanks & Regards,
    Madhu

  6. Simon says:

    It does support this – have a look at this example.

  7. Dnyaneshwar says:

    Hi
    Nice Plugin but it doesn’t work for hidden element.
    eg. if that div is onload hidden and after click that div is display block in this scenario it doesn’t work. Please provide us some solution.

  8. Simon says:

    Ruhollah

    This page works fine. I can’t think that the charset will affect anything in this code. What is it that doesn’t work?

  9. ruhollah says:

    Hi
    It does not support complex characters like Ų“ Ų³ ŲØ (persian and arabic characters)

  10. Simon says:

    Hannah
    That’s not too difficult, but the script would need some amendment as currently it will just slide content in its ‘own’ container.
    Have a look at this.
    You would of course need to ensure that the scrolling content is the same height in each box.

  11. So here is what I am trying to make work…I have three divs all floated against each other. I want the middle div to contain the slider and to correspond and slide the content in the 2 outer divs surroundings this. I’ve gone is circles. Is this possible with the way you have written this script?

  12. Simon says:

    That’s coming from the jQuery UI css, not my css. You’ll need to make some additions to your css to negate the jQuery if you don’t want them.
    Have a look at the section on the plugin page for some help.

  13. Marque says:

    Disregard last post…I had my width to wide for the offset but now I see something I didn’t notice before. The bar itself gets a black bar in the slide area when I slide down a little.

  14. Michele says:

    Thank you! I was indeed using an older version of UI. It works like a charm now, silly me!

  15. Simon says:

    Michele

    I’m guessing that you might be using an older version of jQuery UI with jQuery 1.9? It works fine (just tested!) with jQuery 1.9.1 and jQuery UI 1.10.2.

  16. Michele says:

    Great script! I just can’t seem to be able to make it work with jQuery 1.9.1… Do you have any suggestion? Other than switch back to 1.7.1! šŸ˜‰

  17. Alain says:

    Simon
    And it works ! Simple and clean ! Thank you very much.! I go on exploring this clever script to see how I can manage it into my webdesign and concept. I will give you a feedback about that !

  18. Simon says:

    Alain

    You’re missing a height on #global. Add height:100% to this element and then the ‘Not_OK_test…’ file works.

  19. Alain says:

    Simon
    Thanks for you answer ! I suspect something wrong about CSS too. You can find here a very simple example. If you have a more precise suggestion about what’s wrong ?
    http://www.memoiredimages.fr/docs/Vertical_Scrollbar_Inside_A_Super_Container.zip

  20. Simon says:

    Alain
    That sounds like you just don’t have the css right. To resize the window the #scroll-pane needs to be set with a percentage height and up the DOM structure so that the height changes with the window. It’s hard to suggest anything else without seeing your site, really.

  21. Alain says:

    Simon,

    Thanks for this very interesting summary with a lot of examples ! Regarding Scrollbar resizes with window, I have noticed that it seems not working when the div container #scroll-pane is nested inside another div for example #global. I have some partial result by changing the css this way :
    #global #scroll-pane,.scroll-pane{position:relative}. Nevertheless, the Scrollbar cannot resize with window. Any suggestion for this problem ?

  22. Simon says:

    Walter
    Have a look at the demo pages, and view the page source (Ctrl+U in everything except Internet Explorer, where it’s Page > View Source). This shows the entire page. If you’re still stuck, get back in touch.

  23. Walter Wilson says:

    Looks interesting, and the examples work really well. Alas, the bits of code on offer don’t seem sufficiently complete to adapt to one’s own site – whatever one tries there seems to be something missing.

  24. Simon says:

    Heiko

    I haven’t tested on Android, no. The base issue is that jQuery UI doesn’t currently recognise touch events, I think. I’ve very recently tried using jQuery UI Touch Punch, which works on a quick test on Apple iOS on an iPad. I’d suggest adding this to your page. It works on this test page.

  25. Heiko says:

    Hi,

    great script so far….
    Have u already tested in Android 4.2 (Jelly Bean) with newest Chrome Browser? I dont think that this is the right behaviour…you cant scroll the div anymore by “touching” the content – you have to exactly match the scrollbar. The behaviour of the bar is “Hyperlink-Like”. You ever have to make a click in the wrapper of the scrollbar to scroll – that is not useable… Any suggestions for this problem?

  26. Simon says:

    Pawel

    You’ll need UI Core and UI Slider.

  27. Pawel says:

    Hi, I would like to build a custom download of the jQuery UI. What jQuery UI components are required to make this slider work?

    Thank you

  28. Simon says:

    Hi Huppy

    If you want to use two scrollbars with different images for the handle then there’s two choices:

    – use two different versions of the setSlider() code which apply different images, and call them separately for each scrolled element, or
    – use the plugin version of this code, which supports different images anyway

  29. Huppy says:

    Hey Simon, I was wondering how to have multiple scrollbars that have different styles for each one.
    I’m trying to apply a different scrollbar for the text area I have here: http://www.huppycollective.com/

    Thank you!

  30. Juergen says:

    GREAT
    That was VERY usefull.
    I tried the first 9 hints from http://www.net-kit.com/jquery-custom-scrollbar-plugins/
    But yours coming 10th was the only one working for me

  31. NageswaraRao says:

    Thanks a lot for providing a dynamic solution for multiple problems of Jquery-Div Scrolling.

  32. Simon says:

    Hi Liz

    Start with the multiple slider approach, and then just adapt the additional code for the buttons using a class instead of an id for the buttons. You’ll then need to amend the scrollUp() and scrollDown() functions so they only scroll the relevant slider. I’d do this by adding the scrolling element as an argument to the function and calling this from the bound click event. Hope that helps.

  33. Liz says:

    Hi Simon,
    I see you have examples for the multiple sliders and the slider scrolling via buttons, what would be the best way to have on one page both multiple sliders each with their own buttons, without having all of the sliders scroll at once?

  34. James says:

    This is beautiful, I’ve just emailed 5 examples to myself which I’ve identified as necessary to replace my cludged jquery-1.4 scrollbars. Been looking for a way to replace them so I can update to jquery-1.7 and this fits the bill, I think. Thank you, Simon.

  35. Simon says:

    Hi Jai

    Horizontal sliders are quite different to vertical sliders, so if you want a horizontal the best starting point is this example on the jQuery UI site. You should be able to adapt that code to animate margin-top instead of margin-left to achieve the effect you want.

  36. Jai says:

    Wow, Its very useful for me. Thanks a lot. Can I ask one simple question? Is it possible to make the slider (only the slider not scroll content) horizontal? Which means when move the scroll bar horizontally the content area need to move vertically (Same happening now). Sorry for my bad English.

  37. Tony says:

    yeah i scoped out touch punch, but i liked scrollability (does the same thing but much lighter weight). the only issue is that both of those scripts conflict with your scrollbar; they scroll the content on touchdown, but the scrollbar doesn’t change with the scroll, so it just resets to top 0 on touch up. its rather frustrating being so close to perfection and yet so far.

  38. Simon says:

    Hi Tony

    I don’t have a complete answer to this (as I don’t have a touchpad device…) but: the first port of call ought to be jQuery Mobile, but the slider provided in jQuery mobile looks like it’s just a horizontal one, and further it seems jQuery UI and jQuery Mobile have some difficulty working together anyway. So, it doesn’t look like jQuery Mobile is much help at the moment. Looking at alternatives, this development looks like it might be worth a try.

  39. Tony says:

    Simon – love this script. Great work, truly. Answer to prayers.

    I am banging my head against a wall, though, trying to get it to work on touch devices (specifically tablets, like the ipad). Any ideas?

  40. Simon says:

    Madhav

    Have a look at this implementation of the scrolbar which copes with the content being amended after load:

  41. Madhav says:

    Vertical Scrollbar works fine if the content is hardcoded inside div id=”scroll-pane”. Scrollbar not appearing if the data is loaded dynamically inside scroll-pane div.

    Please help me.

  42. Richard says:

    Great adaptation of the jquery ui. I found I needed a vertical scroller this morning and your adaptation does almost exactly what I needed. I did need to restyle the handle on focus though, so made a couple of changes to the code.
    I’ve put the example of the changes I made on my site: http://www.spainpropertyportal.com/vertical-scroll/
    Feel free to use it if you like it.

  43. Simon says:

    Avex

    If you view any of the demos you can see the html by viewing the source of the page.
    If you mean change the colour of the handle on hover this can be done just with css using the classes that jQuery UI itself adds. On the basic example, try adding the following to the css:

    a.ui-state-hover{background-color:orange}

  44. Avex says:

    Hi Simon, i don’t know how to add your good scroll to site. So can you show instructions and also examples of html code?
    P.S. Can your scroll change the color after mouse over? How to make this?

  45. Simon says:

    Hi xb

    The code can’t be styled directly using the jQuery UI css themes ā€“ the images supplied do not work well with a vertical, as opposed to horizontal slider, and my vertical scrollbar requires an additional enclosing element for the slider, with the result that the wrong element is styled. However, you can get fairly close: more information here.

  46. xb says:

    Awesome plugin!
    Do you plan on adding in integration with the jquery UI themes? This is the only thing holding me back right now since the user can change themes I’d like to have the scroll bar change too.

  47. Simon says:

    Well, I can’t change my css otherwise the slider won’t work….it doesn’t conflict with the jQuery UI base css. I suggest you examine what’s conflicting using a tool like Firebug and take it from there.

  48. D3vilroot says:

    I mean that i’m using your css and also ui css.. i think they are in conflict

  49. Simon says:

    I didn’t build this using the jQuery UI css, so it’s not suprising it doesn’t work, although you can certainly adapt the styling here to produce the same effect.

  50. D3vilroot says:

    I found problematic using your script with
    jquery-ui-1.8.16.custom.css
    when I import ‘ui css’ slider looks bad? Is there a solution to use core ui css and your slider as well?

  51. Simon says:

    Tian, this is what you need:

    $('.scroll-pane').each(function(){
        setSlider($(this));
    });
    $(".slider-wrap").hide();
    $(".scroll-pane").hover(function(){
        $(this).find(".slider-wrap").show();
        },
        function(){
        $(this).find(".slider-wrap").hide();
    });

    Because there are multiple elements with class slider-wrap they need to be qualified via $(this) for the hide and show.

  52. Tian says:

    Hi Simon, fantastic script here, however, I am trying to use both the multiple and auto hide functions together and Im scruggling, this is what I am using:

    $('.scroll-pane').each(function(){
       setSlider($(this));
    });
    setSlider($('.scroll-pane'));
    $(".slider-wrap").hide();
    $(".scroll-pane").hover(function(){
       $(".slider-wrap").show();
    },
    function(){
       $(".slider-wrap").hide();
    });
  53. Simon says:

    Hi Dick

    Thanks for that. As you’ve identified, it looks like the mousewheel plugin needed updating to work with jQuery 1.7.

  54. m4t says:

    Hi Simon, thanks for this simple but very useful code.

    I’m using your multiple scrollbar slider and this is my little contribution:

    if you add this after main if:

    else{ $(this).height($(this).find(‘.scroll-content’).height());}

    div height will change according to effective height. No more blank spaces between content.

    Hope it helps someone…
    byeee

  55. Hey Simon! Thanks again for this great implementation. Recently, I upgraded to jQuery UI 1.8.17 from .13 and jQuery to 1.7.1 from 1.5.1. Since then everything works in the content slider except for the mousewheel.

    In order to use jQuery 1.7.1 and jQuery UI 1.8.17, I upgraded the mousewheel code from 3.0.2 to 3.0.6 which seems to fix the problem of the mousewheel not being able to “scroll” the content slider and its contents. The new mousewheel code (3.0.6) can be found here… https://github.com/brandonaaron/jquery-mousewheel/downloads.

  56. kly411 says:

    Thanks to Simon, Mitch, Brent and all subsequent contributors. This is a major find in my book and pleasantly understandable!

  57. Simon says:

    Laura

    It’s easiest if you just view the source code on the demo page – Ctrl+U in everything except Internet Explorer where it’s Page > View Source.

  58. Laura says:

    can you please include the html in your example

  59. Simon says:

    Varun

    The starting point for this code was the horizontal scrollbar example on the jQuery UI site – you might want to take a look at that.

  60. Varun says:

    Just wondering what parameters need to be changed to make your code scroll horizontal.

  61. Bjƶrn says:

    Thanks a million. Browsed through the web for easily implementable scrollbars, and tried several without success. Yours is working like a charm!

  62. Simon says:

    I’ve added a fix to this problem to the demo.

  63. Mr. Battersby,
    Thanks so much for this great resource. Related to the demo (w/buttons) at…
    http://www.simonbattersby.com/demos/vertical_scrollbar_demo_14_scroll_buttons.htm
    I see some weirdness occur when a user could possibly drag the button image(s) off of the click point. This seems to clog up the behavior of the scrollbar. Sometimes, the handle on the slider will vibrate like it’s confused. Again, this happens only when I drag the images off of the click destination/link area on the buttons. I’ve reproduced it in IE9 and FF 7.0.1. I really like this solution, but I’m hesitant to implement it because of the slight bug I’ve found. Do you have any ideas as to why this is happening? I’m wondering if I assign the click handlers to a container with a background image rather than just use the image themselves, if this will fix the issue. I really appreciate what you’ve done, just wondering if you’d noticed this or had any ideas. Thanks in advance for reviewing.

  64. Mikhail says:

    Thank you! very usefull!

  65. Simon says:

    Yes. For the basic slider, change this:

     $("#scroll-pane").after('<\div id="slider-wrap"><\div id="slider-vertical"><\/div><\/div>');

    to this:

     $("#scroll-pane").before('<\div id="slider-wrap"><\div id="slider-vertical"><\/div><\/div>');

    and then in the css move margin-left:50px from #scroll-pane to #slider-wrap.

  66. Gerben says:

    Is it possible to place the scrollbar at the left side of the div?

  67. Varun says:

    Awesome. Thanks a million!

  68. Simon says:

    The anchors option uses the standard slider options to move – you could try using the animate option on UI Slider – which is what the easing demo uses.

  69. Varun says:

    Is it possible to adjust scrolling speed using anchor variant?

  70. Varun says:

    Hi:

    I tried adding easying variant with anchors but no luck.

  71. Simon says:

    Cristian

    The problem is really that these two aren’t designed to work together – if you’re using a mousewheel you want lots of tiny movements to reflect the scroll – which don’t work well with easing.

  72. Hello

    the easying not really working smooth specially with mouse wheel and you have to let go the scrollbar to actually fire the scroll event

    Any thoughts?

    Cristian

  73. Simon says:

    Joe

    I think this would be rather odd for users – a scrollbar by definition has a stop at the top and a bottom and isn’t endless. What happens when you’ve scrolled to the bottom – does the scrollbar then jump back to the top? If so I’d suggest that is unexpected behaviour for the user.

    On a practical note, the endless slider works by cloning elements before and after the content to give the appearance of an endless scroll – which if combined with a scrollbar will mean the length of the scroll-content will extend – so that would be a challenge to overcome. Overall if you want the endless scrolling effect I would dispense with the scrollbar entirely, and just use .animate() triggered by up and down buttons. This would be both simpler to build and less confusing to the user.

  74. Joe says:

    I would like to implement the example: autohide the scrollbar with endless/infinite scroller. any suggestions?
    Thanks in advance!

  75. Simon says:

    Hi Varun

    You could plug in the code from the easing variant, yes, but again, if you don’t need the scrollbar I’d just use .animate() to move your div.

  76. Varun says:

    thanks Simon for prompt reply. I changed overflow from “auto” to “hidden” in #scroll pane and in worked perfectly.

    However, I was thinking is it possible to use ‘adding easing’ effect with ‘scrolling with anchors’ technique.

  77. Simon says:

    Not very clear what you’re trying to do – if you don’t want the scroller to appear at all you could just hide it with css – but in this case I think it would be easier to dispense with the scrollbar altogether.

  78. Varun says:

    how can I remove scrollbar to appear while using anchors to scroll?

  79. Simon says:

    You need to make sure your vertical and horizontal scrollers are identified with separate ids or classes and that the slider is called and set up separately. If you do this there shouldn’t be a conflict.

  80. mary says:

    Hi,
    This article is really helpful. How can i add both horizontal and vertical slider in the same page.
    Am using http://jqueryui.com/demos/slider/#side-scroll for horizontal scroll, and ur code for vertical scroll bar. Can u please advice how to resolve the conflict when adding both horizontal and vertical slider in same page.Thanks in advance

  81. I just have to say, I’m very impressed with the example code, and your responsiveness to the comments you’ve received from your readers.

    Its great to see when a developer not only posts an awesome solution, but also follows-up and addresses some of the challenges that readers have when implementing your code!

  82. Chetaru says:

    Hi..
    Thanks for sharing this information and resources it’s really help full for me with the help of this we can improve our designs and development I really inspire with this information thanks

  83. Simon Suh says:

    thanks for the blog post, i’m reading over your css so I can learn how to customize the appearnce of my own scrollbar based off the jquery UI. Keep up the good work!

  84. Josh says:

    Simon, have you seen the new scrollbars used in safari? I modified the css slightly and was able to get this same feel using the auto hide solution. Now I just need to add fading animation to the hide. A good example would be the new scrollbar in Facebook for your online friends. Doesn’t show until you rollover, then fades in when rollover and fade out when rollout. Pretty spiffy!

  85. Simon says:

    Added as a variant: auto scroll on load Demo

  86. Jenya says:

    Hello,

    Is it possible to animate the scroll bar? I want it to start moving down automatically once the page is loaded. And stoped once i click on scroller.

    Thank you in advance!

  87. Simon says:

    The approach to take will be very similar to that I’ve employed for my multiple sliders. You would need to wrap all the code that sets the slider up (essentially everything that’s not already in a function) into a new function, and then call this function for each slider using .each() – making sure that. The code is already set up using classes so you shouldn’t need to change the html or css much, if at all.

    Jay – I replied by email to your subsequent comment but apparently your spam filter means I need to complete a form to allow me the privilege of sending you an email. Not welcoming when I’m trying to help you. Perhaps you can unspam and read it.

  88. jay says:

    Simon,

    Thanks for the ā€œmultiple scrollbars on one pageā€ demo. I was at the jQuery UI page, http://jqueryui.com/demos/slider/#side-scroll, and have been looking for horizontal multiple scrollbars for a long time until I found your page.

    I simply need to have multiple horizontal scrollbars on the page using exactly the jQuery UI css and js shown at above URL without having too much code modification. Can you shed some light?

    Thanks.

    Jay

  89. Simon says:

    Vlad

    Yes – there’s an example under variants – here’s the demo. That uses multiple images in just the way you describe.

  90. Vlad says:

    Hi. Is there a way to put an image for the scroll handler so that it streches only in the middle and has its top and bottom rounded, for example? Something like having 3 containers on top of eachother and only the middle one repeats the background.

  91. Simon says:

    Dennis

    Yes – there’s an example under variants – here’s the demo.

  92. dennis says:

    is it somehow possible to set the height of the scroll-pane to 100% so it changes size when resizing the browserwindow?

  93. Simon says:

    I’ve added example under variants – here’s the demo.

  94. danny says:

    First, let me thank you for your code. Thanks to it’s discovery, a nervous breakdown was narrowly averted.

    Is there is a way to add arrow buttons at the bottom? Just as an additional option for the user. So they could control the scroll bar by actually clicking on it, using the mouse/track pad, or using the arrow buttons.

    Any ideas would be greatly appreciated…and the ones presented are already a life-saver!

  95. Simon says:

    Dave

    jQuery UI slider supports this via the ‘step’ option. To use this you need to add the parameter to the javascript:

    $('#slider-vertical').slider({
          orientation: 'vertical',
          step: 10,
          min: 0,
          max: 100,.....
          
  96. Dave says:

    Really excellent code. Any easy way to make it scroll in increments?

  97. Simon says:

    There’s an example for multiple scrollers on a page under the variants section. Demo here.

  98. rajunix says:

    Thank u so much for using UI for scrollbar. But I am using multiple boxes using same code(divs, ids) but it not working. It is useful to work only one scrollbar in the whole page.. I need multiple….. thanku

  99. Gavin says:

    You are an absolute scholar and a gentleman! Thanks so much, not only for your prompt response, but also for taking the time and care to resolve the issue.

    Yes, I spend more time getting IE6,7, 8 and 9 to behave themselves than on the rest of our project tasks put together … well, almost šŸ˜‰

    Silly question though, where do we get the new version of the jQuery UI from?

  100. Simon says:

    Problem was that the version of jQuery UI the pages were using breaks in IE9. Good old IE…..
    I’ve updated the version and it seems fine in IE9 now.

  101. Gavin says:

    Hi Simon

    Thanks for sharing your knowledge! I have used both the standard version of your scrollbar as well as the one using an image for the grip.

    I noticed today that with both versions the grip does not work in I.E.9 I know you do not support your work but was wondering whether you know of any possible reason?

    Thanks again …

    Gavin

  102. Simon says:

    I’ve added a new variant to support scrolling via anchors.

  103. Johnny says:

    Hi,

    Nice scroller. Do it supports scrolling using anchors?

    regards, Johnny

  104. Simon says:

    Hi Ethan

    In some of the other examples above I’ve catered for this by checking if the scrollbar exists – but your solution would work equally well – nice idea.

  105. Thanks for the plugin. I have a gallery that I wanted to be able to scroll larger the large image that’s replaced by thumbnails.

    Long story short the scrollbars were stacking because your code uses “.after()” which will start to stack. I created a div to contain the scroll bar and then used .html() instead so it automatically replaces. That made a little more sense to me personally.

  106. eleni says:

    I use the code from the demo -page.Really helpfull after spending hours on looking for a slider -verical!!Thanks!!!!!

  107. hes says:

    Thanks, man!!! I found one bug with the latest version of jquery. When you drag the slider, sometimes you drag the url instead. Strange. With older version you used is everything ok.

  108. Simon says:

    Alan, if you have a look under “Variations – 26 November 2010 – Using an image for the slider handle” on my page then you’ll see an explanation of how I used images on the scrollbar handle.
    There’s an example page here.

    The example code allows for a separate top and bottom image which would work for your arrows.

  109. Alan says:

    Hi, great bit of code. What would be the best way of adding little arrows heads at the top and bottom of the scroll bar. ?

    Thanks

  110. Simon says:

    Hi Igor

    Thanks, I’ve added another variation above to cope with a percentage height .scroll-pane and window resize. I think however, for a fixed height .scroll-pane I wouldn’t expect a window resize to invoke or remove a scrollbar.

  111. Igor says:

    Hi,

    Great tool, I’ve been playing around a little bit, I had following question/comment:
    Let’s say #scroll-pane is set with a height: 550px, the scroll-content is not much, the scrollbar is not shown…
    After resizing the browserwindow [IE, FF, Opera, …] to a height, let’s say 220px, the scrollbar remains invisible…

    Also, how about a height: 100% instead of a fixed height…

    Kind regards,
    – Igor

  112. Simon says:

    Mike

    Thanks. You’re right, I wasn’t catering for the scrollbar not being required after a resize. I’ve added this to the demo now.

  113. Mike says:

    Great tool. I am using the Ajax version…. there is an issue with the resizing of scroll. The resizing works fine, but fail to hide the scrollbar if it is not required once added already. I think your scripts only appends to the existing scroll but it doesn’t reset the scroll. Is there any way to reset the scroll (ajax version with dynamic content)?

    Regards,
    Mike

  114. Brandon says:

    Very, very good.

  115. george says:

    Thanks so much for this Simon. It’s been a big help.

  116. Simon says:

    Hi Mitch

    Thanks for asking, that’s fine.

    Simon

  117. Mitch Malone says:

    Simon,

    I have partially rewritten this function as a plugin that can be recycled and reused throughout a page. I just thought I’d drop you a note and ask if you mind if I release this plugin on Github, with obvious credit to your original work?

    You can see my code here: http://jsfiddle.net/mitchmalone/XRnxL/

    Kind regards,

    Mitch Malone

  118. Simon says:

    Hi Lorife

    I’ve not built this with the theme in mind, so it doesn’t surprise me that it’s not quite right – in fact the handle moves correctly, but the background to the scrollbar isn’t long enough as you say. I added the #slider-wrap element to cope with this and make it more flexible. However, you can combine the demo with a coloured background and the demo with an image for the handle to create pretty much any styling you want.

  119. lorife says:

    Hi,
    your component is great..but i have a problem when using jquery Ui theme.

    try using your main demo with the standard theme Ui-lightness and you’ll see that the scrollbar is the wrong size..

    please can you fix it?

  120. Ohmish says:

    Hi again
    I fiddled a bit with it, and found out that I could just use this to scroll down:
    $(“#slider-vertical”).slider(“value”, 0);
    $(‘#scroll-content’).css({top:-difference});

  121. Ohmish says:

    Hey Simon

    Do you know an easy way to scroll down to the bottom of the text in your scrollbar?
    Something like
    $(‘#somebutton’).click(function() {
    // scroll down to bottom code
    });

  122. Simon says:

    Hi Brent

    Thanks – I think in fact I originally had it set up as you describe, but added the height setting into the javascript just to make it more portable.

  123. Brent says:

    Hi,

    Thanks for this. I made a small change that might help others in the future.

    I didn’t want the height of the scroll bar to be as long as #scroll-pane, ie: the scroll bar proportions needed calculating based on the height of #slider-wrap, not #scroll-pane. My change also meant I could lose a line of JS and replace it with a single CSS rule.

    What I did in detail:

    Replaced this:

    var handleHeight = Math.round((1-proportion)*$('#scroll-pane').height());//set the proportional height - round it to make sure everything adds up correctly later on
       handleHeight -= handleHeight%2; //ensure the handle height is exactly divisible by two
    
       $("#scroll-pane").after('');//append the necessary divs so they're only there if needed
       $("#slider-wrap").height($("#scroll-pane").height());//set the height of the slider bar to that of the scroll pane

    With this:

    $("#scroll-pane").after('');//append the necessary divs so they're only there if needed
       var handleHeight = Math.round((1-proportion)*$('#slider-wrap').height());//set the proportional height - round it to make sure everything adds up correctly later on
       handleHeight -= handleHeight%2; //ensure the handle height is exactly divisible by two

    … and then gave #slider-wrap a height in CSS.

  124. Simon says:

    Hi Daniel

    Not trivial to adapt for a table I think, because you need two nested elements (#scroll-pane and #scroll-content) to allow the scrolling to work, and the table html construct doesn’t immediately lend itself to this. I haven’t tried this, but an approach might be maybe split thead and tbody into two different tables, then wrap a div around tbody for the scrollng.

  125. Daniel says:

    SImon, thanks this is very close to what I need. Can it be adapted to scroll a tbody while leaving the thead in place?

  126. Simon says:

    Mohsin

    Thanks for your comment. I don’t know what you mean by glitch with scroll speed. If you can give further information I’ll have a look.

  127. mamjed says:

    Amazing! I have been looking for something like this for ages. I have one question, how would I have jquery recalculate the amount needed to be scrolled if I had the contents change size?

    Just saw the alternative method, but there is a glitch, upon resizing the scroll speed gets messed up, and fixes?

  128. Simon says:

    I don’t think the way this works lends itself to using easing – see my reply #26 above.

    EDIT: This is possible with a bit of a tweak – see the example under variations section above.

  129. I was thinking, I will try to do something like this with some easing on the scroll do you think its possible?

    Thanks for setting this up

  130. Simon says:

    Thanks Juan. I’ve added a simple demo adding draggable/droppable to the basic slider to the variations section, and there’s a demo here.demo here.

  131. Juan Olano says:

    This is just great… thanks!!!! At this point I am thinking that this offers a quick way to locate an item.. How abot dragging / dropping capabilities to another div? similar to the Shopping Cart example in jqueryUI.com, where you can drag an element from a Accordion into a basket. I would love to be able to use this that way…

    Thanks!

  132. Simon says:

    Hello again

    If you amend the speed variable on this line:

    var speed = 5;

    then I think that addresses your scroll wheel problem – not something I’ve noticed really. Increasing the speed variable means less mousewheel turns are required. If this still doesn’t do it, then it would be possible to set the variable programatically dependent on the relative size of the scroll pane and the scroll content.

    EDIT: Clicks at the end of the scrollbars should now work OK – see changelog for 16 January, and update 1 March.

  133. Ohm-ish says:

    Some minor “bugs”:

    The less content – the more you have to roll the mousewheel to scroll.
    If the content is only 1 textline bigger than the box, I have to roll the wheel many times to see it (seems like a percentage thing).
    Can I somehow adjust the number of lines the scrollwheel scrolls maybe?

    Clicking on the very top and bottom of the scroll pane has no effect (I have to hit below/over the middle of where the scrollbutton would be)

    Hope it makes sense

  134. Simon says:

    As it stands, I don’t think you could apply easing, as the scrolling is not done via .animate. However, changing this line in the jQuery:

    $('#scroll-content').css({top:topValue});

    to this:

    $('#scroll-content').animate({top:topValue},20)

    Should allow you to use some easing. Having experimented, however, I don’t think it works very well since each individual move of the scrollbar produces only a small animation and hence any easing is not very evident, if at all. Prepared to be corrected on this if anyone has managed it…

    EDIT: OK, corrected myself. The trick is to call the animation from the change event instead of the slide event. Have a look at the example under variations section above.

  135. Ohm-ish says:

    Hey. Nice work!

    Would it be easy/possible (for me or you) to add some easing using jquery?

  136. Simon says:

    See under the variations section for some comments on this, and here for a demo.

  137. rstat1 says:

    First thanks for this awesome bit code. It was big help to me on a current project.

    The only issue I’m having is updating the handle size when content is added via AJAX. It’ll still scroll but the slider goes less than a quarter of the way down and stops, refusing to go any further

  138. Simon says:

    Wow, two requests in the space of a few days asking the same thing! I’ve added this under the variations section, and there’s a demo here.

  139. Randall says:

    Love this simple approach! I have simplified it even more and made some changes for my use but nothing needs to be changed with your code.

    Now how could we get more than one of these to function properly in a page at a time? I would love to be able to use this that way:D

    Cheers!

  140. Ashish says:

    What about using the scrollable DIVs in two tabs? Sorry, its not working at my end while trying with tabs and both tabs may have scrollable DIV. Please suggest.

  141. Simon says:

    Hi Robert

    I’m not quite sure myself whether this makes for a good user experience. However, it’s simply done. I’ve positioned #slider-wrap absolutely within #scroll-pane. This necessitates a change to the css:

    #slider-wrap{position:absolute;top:0;right:0;background-color:lightgrey;width:20px;border-left:1px solid gray;}

    and then using .append instead of .after to insert #slider-wrap:

    $("#scroll-pane").append('<\div id="slider-wrap"><\div id="slider-vertical"><\/div><\/div>');

    and finally adding the show and hide code:

    $("#slider-wrap").hide();//hide the slider after it's set up
    $("#scroll-pane").hover(function(){	$("#slider-wrap").show();},function(){$("#slider-wrap").hide();});//show on hover

    You can see an amended demo here.

  142. Robert says:

    How about auto-hide function?
    If you move mouse out of div region it hides. If you move inside div region it shows on div content (space saving technique).

  143. Simon says:

    Thanks for your comment. My proportion calculation is not wrong – you are achieving the same result by a different way by changing both the proportion and handleHeight calculations.

    Your extra line of code ensuring the handleHeight is divisible by two is a good idea and in some cases stops the handle finishing one pixel short. I’ve added this to the code.

  144. Thom says:

    Hi Simon, thanks for sharing this – however, doing some testing I found the proportion formula to be wrong used to calculate the size of the handle, it should be:

    var proportion = pane.height()/content.height();

    I’ve also tweaked the handle formula a bit ensuring we get whole numbers after multiplying by 0.5:

    var handleHeight = Math.round(proportion*pane.height());
    handleHeight -= handleHeight%2;//Make sure this is divisible by 2 as we're multiplying by 0.5 later on
    
  145. Simon says:

    I’ve added this functionality now – by checking if the scrollbar is required, and only adding if it is.

  146. Jorge says:

    How can I hide the scrollbar when it’s not needed?

  147. Simon says:

    Hi Adrian

    You should be able to do this quite simply by adding the following at the start of the javascript:

    $("#scroll-pane").height($(window).height()-200);//set the scrollpane to the window height - 200px
    $("#slider-wrap").height($("#scroll-pane").height());//set the slider height the same as the scrollpane height
    

    Hope that helps

  148. Adrian says:

    Hi, this is almost exactly what I’ve been looking for, thank you…

    However the one remaining issue I have is I need the height of the scroll area to be the browser height (minus 200px for the header/footer)

    Any ideas?

  149. Simon says:

    Yes, that’s pretty straightforward. I can use the .ui-slider-range element which is created by the javascript. This needs a bit of css:

    .ui-slider-range{background-color:yellow;position:absolute;width:100%}

    and a small addition to the javascript:

    $(".ui-slider-range").css({top:-sliderMargin});

    after the slider height and margins are set. You can see an amended demo here.

  150. Php coder from Goa, India says:

    Hi,
    Is it possible to color scroll bar like this one? http://jqueryui.com/demos/slider/#slider-vertical

    Kind Regards

  151. Simon says:

    Thanks. Yes, my demo page works with the mousewheel anywhere on the page – in a real-life situation you would make the mousewheel more specific using something like:

    $("#mydiv").mousewheel(function(event, delta){...etc
  152. Yann says:

    This is well done and interesting, thanks for sharing… I have added a few lines to my version of your code that enables mousewheel only when the mouse is over the element to scroll, or in the actual state your document (your page) will not scroll at all, only your div will.

    I’m pretty sure I’ve done it the wrong way, that’s why I leave you do it better than me. (for example with my code, I cannot have two scrollbars on the same page, but that’s OK for me).

  153. Winter says:

    Being looking for this solution for so long…… I feel like crying now (believe me), thanks!!!!!!!!

  154. Simon says:

    Rob – you’re right – I’d noticed that myself earlier and never got round to having a look at it. It’s now fixed.

  155. Rob says:

    Great adaptation! Slight problem though, in that the drag bar does not track the exact location of the mouse. I saw that on the demo page under Chrome and IE 8.

  156. Simon says:

    Hi Dan

    Interesting suggestion – I’ve added this functionality to the basic slider here.

  157. Dan says:

    I’ve begun using this to try it out; I was thinking exactly the same… editing the horizontal and the nightmare began ensuing. This is a great solution to an obvious problem, well done.

    I’m intrigued as to whether ‘auto-complete’ type functionality can be factored into this at all? I’ve got a lot of options in my slider (it’s used to navigate through a user’s assets) and quick finding what you want would be a great addition. i.e. moving slider to a position with an event?

    Great to hear your thoughts; and if its just silly.

  158. Simon says:

    Thanks. You could try this plugin for the mousewheel.

    EDIT:Mousewheel support is now included on the demo.

  159. Yves says:

    Thanks for the informative article. Mouse-wheel support would certainly be a great addition !

Useful? Interesting? Leave me a comment

I've yet to find a way of allowing code snippets to be pasted into Wordpress comments - so if you're trying to do this you'd be better off using the contact form.