Custom Scrollbar

Example of custom scrollbar using draggable javascript object. Problems exist when used inside iframes.

by Felipe Alfaro

HTML

<div id="scrollbar"></div>
<div id="scroll-hide">Sed ultricies erat id purus dictum aliquet. Pellentesque lectus sem, convallis id tempor quis, ullamcorper ac tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed dictum malesuada eleifend. Mauris erat nulla, mattis in pulvinar et, pharetra sed neque. In vel nisi nisi. Aenean ut eleifend quam.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent et suscipit quam. Integer non dolor mi, fermentum blandit est. Etiam ultricies tincidunt nisl, ac varius tortor consectetur ac. Aliquam a neque in orci tempor convallis vel aliquam orci. Integer sed cursus risus. Pellentesque tincidunt leo at nibh placerat luctus. Mauris erat ante, eleifend iaculis laoreet a, mattis volutpat ligula. Vestibulum interdum orci sed odio congue in vestibulum massa volutpat. Sed sapien lacus, pretium vel egestas vel, porta vel erat. Suspendisse pulvinar scelerisque risus.

Nam metus mauris, varius et pellentesque viverra, tempus id est. Nullam ornare dui in massa lobortis quis egestas libero tempus. Fusce pulvinar placerat accumsan. Maecenas dolor erat, sollicitudin in pellentesque id, placerat sit amet lacus. Proin ullamcorper orci vitae lectus tincidunt pulvinar. Praesent magna tortor, tincidunt et venenatis vitae, pharetra et justo. Donec mattis molestie elit, at ultrices magna eleifend sed. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed id massa in sem laoreet elementum sed ut nulla.

Nunc libero libero, adipiscing vel condimentum faucibus, ullamcorper vitae libero. Ut sodales viverra mollis. Aliquam tristique purus ut est interdum id rutrum leo commodo. Praesent sit amet tellus mi, in consequat nisl. Vivamus tempus enim in urna posuere eget tincidunt justo dapibus. Nulla molestie, mauris et ultrices vestibulum, ipsum justo imperdiet felis, id pharetra justo sem vel turpis....

CSS

div#scrollbar {
  width: 12px;
  min-height: 12px;
  background: rgba(0,0,0,.2);
  position: relative;
  right: 1px;
  border-radius: 200px;
  z-index: 100;
  cursor: default;
}

div#scrollbar:hover {
  background: red;
}

div#scroll-hide {
  position: absolute;
  border: 1px solid orange;
  padding-right: 30px;
  left: 0;
  right: -30px;
  top: 0;
  bottom: 0;
  overflow: auto;
}

body {
  overflow: hidden;
}

JavaScript

// Problems exist with iframes

var window_h;
var scroll_ratio;
var $scrollbar = jQuery("#scrollbar");
var $scrollable = jQuery("#scroll-hide");
var $scroll_buffer = 1;
var dragging = null;

// update size and position of scrollbar
function update_scroll(scroll_content) {
	scroll_content = typeof scroll_content !== 'undefined' ? scroll_content : true;
	
	// determine scrollbar size
	window_h = jQuery(window).height();
	scroll_ratio = window_h / $scrollable.get(0).scrollHeight;
	if (scroll_ratio >= 1) {
	// no scrolling necessary
		$scrollbar.css("height", 0);
		return;
	}
	var size = window_h * scroll_ratio;
	$scrollbar.css("height", size);
	
	// determine scrollbar position
	// move content
	scroll_ratio = (window_h - $scrollbar.height() - 2 * $scroll_buffer) / ($scrollable.get(0).scrollHeight - $scrollable.height());
	if (scroll_content) {
		$scrollable.scrollTop( ($scrollbar.offset().top - $scroll_buffer) / scroll_ratio );
	} else {
		$scrollbar.offset({ top:($scrollable.scrollTop() * scroll_ratio) + $scroll_buffer });
	}
}

jQuery(document).ready(function() {
	$scrollbar = jQuery("#scrollbar");
	$scrollable = jQuery("#scroll-hide");
	$scroll_buffer = 1;
	dragging = null;
	update_scroll(false);
	$scrollbar.css('right', $scroll_buffer);
	$scrollable.on("scroll", function() {
		update_scroll(false);
	});
});

jQuery(window).on("resize", function() {
	update_scroll(false);
});

function limit(y, el_h) {
	return Math.max($scroll_buffer, Math.min(y, window_h - el_h - $scroll_buffer));
}

$scrollbar.on("mousedown", function(e) {
	dragging = {
		z_idx: $scrollbar.css('z-index'),
        drg_h: $scrollbar.outerHeight(),
		pos_y: e.clientY - $scrollbar.offset().top
	};
	$scrollbar.css('z-index', 1000);
	$scrollbar.addClass('active-scroll');
	if (e.target.setCapture) e.target.setCapture();
	e.preventDefault(); // disable selection
});

$scrollbar.on("losecapture", function() {
	dragging = null;
});

document.addEventListener("mouseup", function() {
	if (!dragging)...