jQuery

Scrollbar replacements

Works with:
FF3
Chrome
IE6
IE7
IE8
Opera
Safari

Description

Scrollbars have been customisable using CSS since Internet Explorer 5 (point something) but was discarded by w3c. Now you can again theme those scrollbars by replacing them with JavaScript alternatives. These are fully themable allowing their behaviour to be determined as well as their look.

This script uses the 'jquery.corner' plugin for the lovely cross-browser rounded corners and 'jquery.drag' for more reliable drag event registering.

Warning: This script has not been extensively tested and should not be used in commercial products without first testing. You have been warned.

Demo

Without JavaScript

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam iaculis malesuada libero vitae consectetur. Etiam vel nisi sit amet tellus tincidunt adipiscing. Nullam faucibus arcu at massa vulputate iaculis. Nunc purus nunc, pellentesque in iaculis at, sodales eget metus. Aliquam tempus, eros id porttitor posuere, neque orci fringilla dolor, et euismod turpis libero vel nibh. Pellentesque accumsan elementum mi, consequat ultricies orci suscipit sit amet. Curabitur ultrices, magna a blandit aliquet, velit elit congue velit, eget suscipit felis odio commodo nisl. Maecenas quis arcu nisi. Mauris vel nisi et mi pellentesque venenatis nec eget purus. Vivamus eu lectus metus, a congue metus. Ut quis magna leo, vel dictum lorem. Mauris ut leo in nulla convallis consequat. Nam vel urna adipiscing orci placerat tristique. Donec volutpat molestie rutrum. Curabitur condimentum pretium ligula, eget consectetur odio vestibulum non. Vivamus ut molestie eros. Suspendisse metus orci, tincidunt in lacinia pharetra, elementum ut tortor. Quisque auctor ultrices augue, ac aliquam lectus porttitor quis.

Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras sed lacus est, quis molestie eros. Nam tincidunt odio id sem condimentum non tempus odio sagittis. Donec vitae euismod leo. Vestibulum et pellentesque dolor. Sed vestibulum felis quis mi placerat aliquam. Aenean ut mattis enim. Donec aliquet vestibulum nisi, condimentum ornare metus venenatis a. Nullam sed odio a dui pretium mollis et ac arcu. Etiam dignissim mattis elit, eu facilisis tellus pharetra et. Vestibulum vel magna sapien, ac suscipit sem. Integer cursus, neque sed congue pulvinar, lectus sapien varius ipsum, eu condimentum urna dolor sit amet felis.

Praesent viverra ullamcorper molestie. Etiam a accumsan sapien. Donec faucibus vulputate dolor eu porta. Nullam luctus, massa non pharetra facilisis, neque tellus accumsan justo, eget sodales libero magna sollicitudin nisi. Nullam tortor sem, vestibulum in sagittis quis, ultricies iaculis dui. Etiam purus enim, congue id vehicula non, egestas non est. Ut consectetur, sem nec rutrum placerat, tortor eros semper turpis, sagittis posuere felis ipsum ac mauris. Donec pulvinar, odio ut fringilla dictum, lacus urna volutpat justo, a vehicula lectus tellus non nulla. Nullam feugiat risus sed tellus pulvinar placerat. Donec sem lorem, condimentum posuere vehicula sit amet, vestibulum a diam. Curabitur a nunc nunc. Aliquam egestas sem sit amet orci pretium egestas sit amet ut justo. Integer condimentum, metus et auctor blandit, ante diam placerat ligula, at semper risus turpis et lectus. Morbi tempus elementum urna, et tincidunt tortor pulvinar id.

With JavaScript

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam iaculis malesuada libero vitae consectetur. Etiam vel nisi sit amet tellus tincidunt adipiscing. Nullam faucibus arcu at massa vulputate iaculis. Nunc purus nunc, pellentesque in iaculis at, sodales eget metus. Aliquam tempus, eros id porttitor posuere, neque orci fringilla dolor, et euismod turpis libero vel nibh. Pellentesque accumsan elementum mi, consequat ultricies orci suscipit sit amet. Curabitur ultrices, magna a blandit aliquet, velit elit congue velit, eget suscipit felis odio commodo nisl. Maecenas quis arcu nisi. Mauris vel nisi et mi pellentesque venenatis nec eget purus. Vivamus eu lectus metus, a congue metus. Ut quis magna leo, vel dictum lorem. Mauris ut leo in nulla convallis consequat. Nam vel urna adipiscing orci placerat tristique. Donec volutpat molestie rutrum. Curabitur condimentum pretium ligula, eget consectetur odio vestibulum non. Vivamus ut molestie eros. Suspendisse metus orci, tincidunt in lacinia pharetra, elementum ut tortor. Quisque auctor ultrices augue, ac aliquam lectus porttitor quis.

Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras sed lacus est, quis molestie eros. Nam tincidunt odio id sem condimentum non tempus odio sagittis. Donec vitae euismod leo. Vestibulum et pellentesque dolor. Sed vestibulum felis quis mi placerat aliquam. Aenean ut mattis enim. Donec aliquet vestibulum nisi, condimentum ornare metus venenatis a. Nullam sed odio a dui pretium mollis et ac arcu. Etiam dignissim mattis elit, eu facilisis tellus pharetra et. Vestibulum vel magna sapien, ac suscipit sem. Integer cursus, neque sed congue pulvinar, lectus sapien varius ipsum, eu condimentum urna dolor sit amet felis.

Praesent viverra ullamcorper molestie. Etiam a accumsan sapien. Donec faucibus vulputate dolor eu porta. Nullam luctus, massa non pharetra facilisis, neque tellus accumsan justo, eget sodales libero magna sollicitudin nisi. Nullam tortor sem, vestibulum in sagittis quis, ultricies iaculis dui. Etiam purus enim, congue id vehicula non, egestas non est. Ut consectetur, sem nec rutrum placerat, tortor eros semper turpis, sagittis posuere felis ipsum ac mauris. Donec pulvinar, odio ut fringilla dictum, lacus urna volutpat justo, a vehicula lectus tellus non nulla. Nullam feugiat risus sed tellus pulvinar placerat. Donec sem lorem, condimentum posuere vehicula sit amet, vestibulum a diam. Curabitur a nunc nunc. Aliquam egestas sem sit amet orci pretium egestas sit amet ut justo. Integer condimentum, metus et auctor blandit, ante diam placerat ligula, at semper risus turpis et lectus. Morbi tempus elementum urna, et tincidunt tortor pulvinar id.

JavaScript

  1. $(function() {
  2.     //replace placeholders with actual scrollbars
  3.     var ORIG_SCROLLBAR_WIDTH = 18;
  4.    
  5.     $.each($(".with_js"), function() {     
  6.         //get the original height
  7.         var scrollArea = $(this);
  8.         var origHeight = scrollArea.height();
  9.         scrollArea.height("auto");
  10.        
  11.         //prepare the container for new scrollbar
  12.         scrollArea.css("overflow", "hidden");
  13.         scrollArea.css("padding-right", parseInt(scrollArea.css("padding-right")) + ORIG_SCROLLBAR_WIDTH);
  14.         scrollArea.width(parseInt(scrollArea.width()) - ORIG_SCROLLBAR_WIDTH);
  15.         scrollArea.append("<div class=\"v_scrollbar\"><div class=\"v_scrollbar_move\"></div></div>");
  16.        
  17.         //get the scrollable height
  18.         var scrollHeight = scrollArea.innerHeight();
  19.         scrollArea.height(origHeight);
  20.        
  21.         //variable declarations
  22.         var scrollbar = scrollArea.find(".v_scrollbar");
  23.         var mover = scrollbar.find(".v_scrollbar_move");
  24.         var scrollerHeight = parseInt(scrollbar.outerHeight(true));
  25.        
  26.         //EVENTS
  27.         scrollbar.bind("mouseover", function(e) {
  28.             $(this).stop();
  29.             $(this).animate({opacity:1.0},400);
  30.         });
  31.        
  32.         scrollbar.bind("mouseleave", function(e) {
  33.             if (!mover.data("dragged")) {
  34.                 $(this).stop();
  35.                 $(this).animate({opacity:0.3},400);
  36.             }
  37.         });
  38.        
  39.         mover.bind("mousedown", function(e) {
  40.             $(this).data("clickY", e.pageY-this.offsetTop);
  41.         });
  42.        
  43.         mover.bind("dragstart", function(e) {
  44.             $(this).data("dragged",true);
  45.         });
  46.        
  47.         mover.bind("drag", function(e) {
  48.             var newHeight = parseInt($(this).css("top")) + parseInt(e.pageY-this.offsetTop) - parseInt($(this).data("clickY"));
  49.            
  50.             updatePosition(newHeight);
  51.         });
  52.        
  53.         function updatePosition(newHeight) {           
  54.             newHeight = Math.max(newHeight, 0);
  55.             newHeight = Math.min(newHeight, parseInt(scrollbar.innerHeight())-parseInt(mover.outerHeight(true)));
  56.  
  57.             mover.css("top",  newHeight);
  58.            
  59.             var contentHeight = (newHeight/(scrollerHeight-parseInt(mover.height()))) * (scrollHeight-scrollerHeight);
  60.             scrollbar.css("top", contentHeight);
  61.             scrollArea.scrollTop(contentHeight);
  62.         };
  63.        
  64.         mover.bind("dragend", function(e) {
  65.             $(this).data("dragged",false);
  66.             scrollbar.stop();
  67.             scrollbar.animate({opacity:0.3},400);
  68.         });
  69.        
  70.         scrollArea.bind("mousewheel", function(event, delta) {
  71.             var scrollPos = mover.position().top;
  72.             scrollPos -= delta*15;
  73.            
  74.             updatePosition(scrollPos);
  75.            
  76.             return false;
  77.         });
  78.        
  79.         //START
  80.        
  81.         //defaults
  82.         scrollbar.css("top", 0);
  83.         scrollArea.css("top",  0);
  84.         scrollArea.scrollTop(0);
  85.         mover.css("top", 0);
  86.         mover.height(((scrollerHeight/scrollHeight)*100) + "%");
  87.         mover.data("dragged",false);
  88.        
  89.         //turn scrollbar on/off
  90.         if (scrollerHeight>=scrollHeight) {
  91.             scrollArea.css("padding-right", parseInt($(this).css("padding-right"))-ORIG_SCROLLBAR_WIDTH);
  92.             scrollArea.width(parseInt($(this).width())+ORIG_SCROLLBAR_WIDTH);
  93.             scrollbar.hide();
  94.         }
  95.     });
  96.    
  97.     //round off the scrollbars and scroll areas
  98.     $(".vertical_scroll").corner("10px");
  99.     $(".v_scrollbar").corner("20px");
  100.     $(".v_scrollbar_move").corner("10px");
  101. });
  102.  

CSS

  1. .demo_box {
  2.     overflow-x: hidden;
  3.     overflow-y: auto;
  4.     height: 400px;
  5.     border: 1px solid black;
  6.     margin: 10px;
  7.     padding: 10px;
  8.     position: relative;
  9.     white-space: normal;
  10. }
  11.  
  12. .v_scrollbar {
  13.     position: absolute;
  14.     top: 0px;
  15.     right: 1px;
  16.     width: 18px;
  17.     height: 100%;
  18.     background-color: #EEE;
  19.     opacity: 0.3;
  20. }
  21.  
  22. .v_scrollbar_move {
  23.     position: absolute;
  24.     top: 0px;
  25.     width: 10px;
  26.     height: 20px;
  27.     background-color: #333;
  28.     cursor: pointer;
  29.     margin: 4px;
  30. }
  31.  
  32. .end_marker:before,
  33. .end_marker:after {
  34.     clear: both;
  35.     display: inline-block;
  36.     content: ".";
  37.     line-height: 0px;
  38.     height: 0px;
  39.     visibility: hidden;
  40. }
  41.  
  42. .end_marker {
  43.     width: 100%;
  44.     clear: both;
  45.     float: left;
  46.     height: 20px;
  47. }

XHTML

  1. <p>
  2.     Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam iaculis malesuada libero vitae consectetur. Etiam vel nisi sit amet tellus
  3.     tincidunt adipiscing. Nullam faucibus arcu at massa vulputate iaculis. Nunc purus nunc, pellentesque in iaculis at, sodales eget metus.
  4.     Aliquam tempus, eros id porttitor posuere, neque orci fringilla dolor, et euismod turpis libero vel nibh. Pellentesque accumsan elementum
  5.     mi, consequat ultricies orci suscipit sit amet. Curabitur ultrices, magna a blandit aliquet, velit elit congue velit, eget suscipit felis
  6.     odio commodo nisl. Maecenas quis arcu nisi. Mauris vel nisi et mi pellentesque venenatis nec eget purus. Vivamus eu lectus metus, a congue
  7.     metus. Ut quis magna leo, vel dictum lorem. Mauris ut leo in nulla convallis consequat. Nam vel urna adipiscing orci placerat tristique.
  8.     Donec volutpat molestie rutrum. Curabitur condimentum pretium ligula, eget consectetur odio vestibulum non. Vivamus ut molestie eros.
  9.     Suspendisse metus orci, tincidunt in lacinia pharetra, elementum ut tortor. Quisque auctor ultrices augue, ac aliquam lectus porttitor
  10.     quis.
  11. </p>
  12.  
  13. <p>
  14.     Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras sed lacus est, quis molestie eros. Nam
  15.     tincidunt odio id sem condimentum non tempus odio sagittis. Donec vitae euismod leo. Vestibulum et pellentesque dolor. Sed vestibulum felis
  16.     quis mi placerat aliquam. Aenean ut mattis enim. Donec aliquet vestibulum nisi, condimentum ornare metus venenatis a. Nullam sed odio a
  17.     dui pretium mollis et ac arcu. Etiam dignissim mattis elit, eu facilisis tellus pharetra et. Vestibulum vel magna sapien, ac suscipit sem.
  18.     Integer cursus, neque sed congue pulvinar, lectus sapien varius ipsum, eu condimentum urna dolor sit amet felis.
  19. </p>
  20.  
  21. <p>
  22.     Praesent viverra ullamcorper molestie. Etiam a accumsan sapien. Donec faucibus vulputate dolor eu porta. Nullam luctus, massa non pharetra
  23.     facilisis, neque tellus accumsan justo, eget sodales libero magna sollicitudin nisi. Nullam tortor sem, vestibulum in sagittis quis,
  24.     ultricies iaculis dui. Etiam purus enim, congue id vehicula non, egestas non est. Ut consectetur, sem nec rutrum placerat, tortor eros
  25.     semper turpis, sagittis posuere felis ipsum ac mauris. Donec pulvinar, odio ut fringilla dictum, lacus urna volutpat justo, a vehicula
  26.     lectus tellus non nulla. Nullam feugiat risus sed tellus pulvinar placerat. Donec sem lorem, condimentum posuere vehicula sit amet,
  27.     vestibulum a diam. Curabitur a nunc nunc. Aliquam egestas sem sit amet orci pretium egestas sit amet ut justo. Integer condimentum, metus
  28.     et auctor blandit, ante diam placerat ligula, at semper risus turpis et lectus. Morbi tempus elementum urna, et tincidunt tortor pulvinar
  29.     id.
  30. </p>