Intro: Customised scrollbar as part of the solution to cross-browser compatibility
Cross-browser compatibility is certainly something painful during web development. One thing you may find annoying is that the scrollbars in different browsers and different operating systems are rarely the same. While some scrollbars take up space, some do not. While some look traditional, some look trendy. For some reasons, you may want to customise the scrollbar of your page or add a scrollbar to a div in your page. I have tried hard to look for a website or a blog post which introduce a simple way to customise a scrollbar which works perfectly across browsers and OS, but I could hardly find one. As a master of scrollbar, I am here to introduce to you the simplest way to customise your scrollbar in a way that it looks exactly the same in any machines.
Preparation: 1 simple scrollbar plugin
I had searched for some JavaScript plugins of which the setup is really really simple and intuitive. After searching for ages, I eventually found one, baron.js. (There are some other plugins but this one is really easy to set up). We are going use baron in this tutorial and you can download baron from: https://github.com/Diokuz/baron
Although the setup of baron is simple, it is capable of creating fancy and complicated scrollbars and scrolling effects. With baron, we can make a scrollbar which:
- appears only when the content overflows the scrollable area
- appears only when we the div is on hover
So, it's time to bail you out of the plight of cross-browser scrollbar. Here are the preparatory steps:
- Download baron.min.js from the link above
- Create an html document and link the necessary library, plugin and CSS file through the html document. We will need 1) baron.min.js (of course) 2) jQuery library 3) style.css (a CSS file to style the scrollbar) 4) main.js (to set up the scrollbar)
Our HTML file is like this now:
<html>
<head>
<title>scrollbar</title>
<link type="text/css" rel="stylesheet" href="style.css">
<script src="baron.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
I prefer to put external JavaScript libraries inside the head tag and my own JavaScript files at the bottom of body. HTML file is compiled from the top to the bottom and our own JavaScript files use the libraries. If our JS files are included before the library files, the syntax from the libraries in our JS files is undefined.
HTML: 2 essential elements
To replace the default scrollbar of the browser, we need two HTML elements. Obviously, we need a div for the new scrollbar. Another thing we need is a div for the scrollable area (Let me call this area scroller). If the content inside the scroller is longer than the scroller itself, our scrollbar will appear.
// HTML COMPLETED!!
<html>
<head>
<title>scrollbar</title>
<link type="text/css" rel="stylesheet" href="style.css">
<script src="baron.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
<div class="scroller">
<div class="content"></div>
</div>
<div class="scrollbar"></div>
<script src="main.js"></script>
</body>
</html>
But, how can our amazing baron know if the content is longer than scroller. We need to look into our CSS file.
CSS: 3 things to make it work
To make our scrollbar works properly, there are three things that we need to bear in mind:
- The scrollable area need to have a fixed height. With baron, besides scroller and the scrollbar, there is a third element which is important. Let's call it root. A root is basically the parent of scroller (
<body>in our example). Baron works in a way such that when it knows that the height of the content is larger than that of the scroller, a class called baron is added to the root element. By default, only when the scrollbar is wrapped inside an element with the class name baron, the scrollbar is shown. So, we must explicitly set the height of the scroller. What I am going to do is to set the height of html, body, and scroller to 100% so that:
height of html = height of body = height = scroller = height of window - Make the root not scrollable (overflow-y: hidden) while the scroller itself scrollable (overflow-y: scroll).
- Style the scrollbar to make it look elegant. (You want to have a nice scrollbar, right?)
// CSS COMPLETED!!
html {
height: 100%;
overflow: hidden;
}
body {
height: 100%;
}
.scroller {
overflow-y: scroll;
overflow-x: hidden;
height: 100%;
}
.content {
height: 2000px;
width: 200px;
background-color: gray;
}
.scrollbar {
display: none;
}
.baron .scrollbar {
display: block;
position: absolute;
background: black;
z-index: 999;
border-radius: 3px;
right: 2px;
width: 7px;
opacity: 0.7;
}
Two things to note:
- Content's height is set to 2000px so that it is longer than the window
- When the content is shorter than the window, the scrollbar uses this styling rule:
.scrollbar {
display: none;
}
When the content is longer than the window, a class baron is added to the root (<body>). So, the scrollbar uses:
.baron .scrollbar {
display: block;
position: absolute;
background: black;
z-index: 999;
border-radius: 3px;
right: 2px;
width: 7px;
opacity: 0.7;
}
JavaScript: Set up the 4 parameters
You may wonder where I am using jQuery. I am only using the ready event in jQuery so that the function is called only after all HTML elements are loaded. As I have said, it is a easy-to-setup scrollbar.
// JAVASCRIPT COMPLETED!!
In our main.js, do the following:
$(function(){
var params = {
root: 'body',
scroller: '.scroller',
bar: '.scrollbar',
barOnCls: 'baron'
};
baron(params);
});
The values for the first 3 parameters are the selector names for the root, the scroller and the scrollbar respectively. But, what about the last one, barOnCls? As mentioned before, when the content overflows the scroller, a class is added to the root. barOnCls is the name of this class.
Extra: Adding a scrollbar to a div?
You may ask: How can I add scrollbar to a div? The idea is completely the same as above. It is probably a good chance to summerise a bit while teaching you how to do it.
- In HTML, create a div with a scroller div and a scrollbar div inside
- In CSS, fix the height of the root, set the height of scroller to 100%
- In the JS file, set the 4 parameters root, scroller, bar and barOnCls and pass the parameter object to baron.
Advanced: An object oriented approach
Sometimes, you may want to create two scrollbars, one for the whole page while another one for a div inside the page. It is better to create a class for the scrollbar objects.
I would create another file named scrollbar.js. In the following, setEffect is to create the effect such that when the mouse pointer enters the div, the scrollbar shows up and when the mouse pointer leaves, the scrollbar disappears.
function scrollbar(root, scroller, scrollbar) {
this.root = root;
this.scroller = scroller;
this.scrollbar = scrollbar;
};
scrollbar.prototype.init = function() {
var params = {
root: this.root,
scroller: this.scroller,
bar: this.scrollbar,
barOnCls: 'baron'
};
baron(params);
}
scrollbar.prototype.setEffect = function() {
var selectorName = this.root + ' ' + this.scrollbar;
$(selectorName).css('display', 'none');
$(this.root).hover(
function() {
$(selectorName).fadeIn();
},
function() {
$(selectorName).fadeOut();
}
);
}
For those who have no idea how to create a class using JS, here is a quick review of the essence of a class in JS:
- Create a class with function, this function is a constructor itself (the function scrollbar above is a constructor)
- Class properties are added to the constructor function while class methods are added by prototype as above
- Inside the constructor or other functions inside the class, 'this' refers to this object (not class). Use 'this' for all the properties inside the class
So, in main.js, you can do:
$(function(){
var outerScrollbar = new scrollbar('body', '.scroller', '.scrollbar');
var innerScrollbar = new scrollbar('.container', '.scroller', '.scrollbar');
outerScrollbar.init();
innerScrollbar.init();
innerScrollbar.setEffect();
});
DEMO:
- Scrollbar for a page without OOP
https://github.com/miruappy/scrollbar
http://rawgit.com/miruappy/scrollbar/master/index.html - Scrollbar for a page and a container without OOP
https://github.com/miruappy/scrollbar/tree/page-div-scrollbar-noOOP
http://rawgit.com/miruappy/scrollbar/page-div-scrollbar-noOOP/index.html - Scrollbar for a page and a container with OOP
https://github.com/miruappy/scrollbar/tree/page-div-scrollbar-OOP
http://rawgit.com/miruappy/scrollbar/page-div-scrollbar-OOP/index.html