Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
153
rated 0 times [  160] [ 7]  / answers: 1 / hits: 18277  / 10 Years ago, fri, december 5, 2014, 12:00:00

I have looked at I think all the scrollbars code but have not yet been able to find a simple one that does not use jQuery or a somewhat complex library.



Has anyone created there own simple scrollbar using just Javascript? What I am looking for is an example of how this can be done. In particular I have a simple Bootstrap web page with:



<body>
<header> ....</header>
<main> ......</main>
</body>


What I would like to do is to be able to have a small in page scroll bar appear to the right of the <main> area if the content there is larger than will fit on a single page. For styling purposes I would like this not to be the browser default scroll bar.



Here's an example of what I am looking for but this one does use jQuery so I cannot use it on my site:



http://manos.malihu.gr/repository/custom-scrollbar/demo/examples/complete_examples.html



I am looking for some way to do this using Javascript in a modern browser IE9 and above. As I think this would be useful for many people I have opened up a bounty of 200 for this in the hope that someone could provide a good example of a draggable page scrollbar that also would respond to the mousewheel when over the page content area.



Just an update. I am not looking for a mobile solution for this. I am just looking for a solution that would work inside a PC / Mac browser. The site is not set up or suitable for a phone. It's possible to use on an IPad / tablet but for those needs I would like to be able to have the scrollbar default to use just the normal tablet scrolling method.


More From » html

 Answers
22

Surprisingly, there is not a great, simple solution out there using vanilla JavaScript. I made a pure JS lightweight, minimal cross browser solution. Adjust to your own needs and aesthetics



*Update 2019

The W3C has a working document that is on standards track to improve this out of the box through the css specification. Although limiting, if you want to use cutting edge css you can now style your scroll bars through the scrollbar-color and scrollbar-width. For more information please check https://drafts.csswg.org/css-scrollbars/



Examples:

Here is the fiddle and CodePen



HTML



<body>
<div id=main class=scrollable>
<div class=content-wrapper>
<div class=content>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Incidunt accusamus maxime voluptatem quasi. Recusandae optio nobis ratione iste consectetur consequatur cupiditate saepe laborum natus neque a provident eum explicabo delectus qui accusantium nostrum reiciendis soluta hic ut at sed laboriosam possimus repudiandae deserunt velit rerum. Aliquam ratione itaque corrupti aperiam quisquam unde aspernatur odio id repellendus corporis eaque expedita in ab minus possimus! Quo tempore consequatur repellat consectetur nemo molestiae perferendis ipsum esse nesciunt blanditiis nobis dicta? Laudantium quaerat inventore deleniti exercitationem explicabo quos pariatur sunt earum labore sed eius blanditiis architecto consequuntur ad consectetur unde sapiente nisi. Sunt eos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Incidunt accusamus maxime voluptatem quasi. Recusandae optio nobis ratione iste consectetur consequatur cupiditate saepe laborum natus neque a provident eum explicabo delectus qui accusantium nostrum reiciendis soluta hic ut at sed laboriosam possimus repudiandae deserunt velit rerum. Aliquam ratione itaque corrupti aperiam quisquam unde aspernatur odio id repellendus corporis eaque expedita in ab minus possimus! Quo tempore consequatur repellat consectetur nemo molestiae perferendis ipsum esse nesciunt blanditiis nobis dicta? Laudantium quaerat inventore deleniti exercitationem explicabo quos pariatur sunt earum labore sed eius blanditiis architecto consequuntur ad consectetur unde sapiente nisi. Sunt eos.</p>
</div>
</div>
</div>
<div>Not special and not contained within scrolling</div>
</body>


CSS



.scrollable {
padding: 0% 10%;
position: relative;
border: 1px solid gray;
overflow: hidden;
height: 400px;
}

.scrollable.showScroll::after {
position: absolute;
content: '';
top: 5%;
right: 7px;
height: 90%;
width: 3px;
background: rgba(224, 224, 255, .3);
}

.scrollable .content-wrapper {
width: 100%;
height: 100%;
padding-right: 50%;
overflow-y: scroll;
}
.scroller {
z-index: 5;
cursor: pointer;
position: absolute;
width: 10px;
border-radius: 5px;
background: rgb(111, 111, 190);
top: 0px;
right: 3px;
-webkit-transition: top .08s;
-moz-transition: top .08s;
-ms-transition: top .08s;
-o-transition: top .08s;
transition: top .08s;
}
.content {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}


JS



(function () {

var scrollContainer = document.querySelector('.scrollable'),
scrollContentWrapper = document.querySelector('.scrollable .content-wrapper'),
scrollContent = document.querySelector('.scrollable .content'),
contentPosition = 0,
scrollerBeingDragged = false,
scroller,
topPosition,
scrollerHeight;

function calculateScrollerHeight() {
// *Calculation of how tall scroller should be
var visibleRatio = scrollContainer.offsetHeight / scrollContentWrapper.scrollHeight;
return visibleRatio * scrollContainer.offsetHeight;
}

function moveScroller(evt) {
// Move Scroll bar to top offset
var scrollPercentage = evt.target.scrollTop / scrollContentWrapper.scrollHeight;
topPosition = scrollPercentage * (scrollContainer.offsetHeight - 5); // 5px arbitrary offset so scroll bar doesn't move too far beyond content wrapper bounding box
scroller.style.top = topPosition + 'px';
}

function startDrag(evt) {
normalizedPosition = evt.pageY;
contentPosition = scrollContentWrapper.scrollTop;
scrollerBeingDragged = true;
}

function stopDrag(evt) {
scrollerBeingDragged = false;
}

function scrollBarScroll(evt) {
if (scrollerBeingDragged === true) {
var mouseDifferential = evt.pageY - normalizedPosition;
var scrollEquivalent = mouseDifferential * (scrollContentWrapper.scrollHeight / scrollContainer.offsetHeight);
scrollContentWrapper.scrollTop = contentPosition + scrollEquivalent;
}
}

function createScroller() {
// *Creates scroller element and appends to '.scrollable' div
// create scroller element
scroller = document.createElement(div);
scroller.className = 'scroller';

// determine how big scroller should be based on content
scrollerHeight = calculateScrollerHeight();

if (scrollerHeight / scrollContainer.offsetHeight < 1){
// *If there is a need to have scroll bar based on content size
scroller.style.height = scrollerHeight + 'px';

// append scroller to scrollContainer div
scrollContainer.appendChild(scroller);

// show scroll path divot
scrollContainer.className += ' showScroll';

// attach related draggable listeners
scroller.addEventListener('mousedown', startDrag);
window.addEventListener('mouseup', stopDrag);
window.addEventListener('mousemove', scrollBarScroll)
}

}

createScroller();


// *** Listeners ***
scrollContentWrapper.addEventListener('scroll', moveScroller);
}());


The concept is simple. We have a main div with a 'scrollable' class. The JavaScript recognizes this element and appends a scroller div that you can style yourself with CSS. By nesting the content-wrapper child div we can effectively push the native scroller outside of the parent div while still controlling padding.



Here is a diagram:
Scroll



The reason we need to maintain native scrolling ability is because the JavaScript scroll event only fires on elements that have overflow set to scroll. See MDN reference on scroll. The benefit being that if JS is disabled, we will still gracefully fallback to scrolling without a scrollbar.






NOTE

You should note that you will have to adjust your version to recalculate the scroller size in certain cases:

1.) Where the screen is resized or

2.) If more content is appended.



Secondly, modifications will have to be made if you have multiple 'scrollable' elements. In this case, you will need to loop over those elements to both append a scroller div and listen for the scroll event.


[#68571] Wednesday, December 3, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
deonkalvinw

Total Points: 409
Total Questions: 96
Total Answers: 89

Location: Saint Pierre and Miquelon
Member since Sun, Nov 27, 2022
2 Years ago
deonkalvinw questions
Sun, Feb 6, 22, 00:00, 2 Years ago
Tue, Dec 28, 21, 00:00, 2 Years ago
Sun, Aug 22, 21, 00:00, 3 Years ago
Sun, Mar 7, 21, 00:00, 3 Years ago
;