Custom scrollbar
How do I make an custom scrollbar?
A class to make custom scrollbar.. What is a custom scrollbar? How do you make a custom scrollbar? This script and codes were developed by Anthony Pothin on 17 January 2023, Tuesday.
Custom scrollbar - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>custom scrollbar</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div class="box" style="background-color: #7FFCFC;"> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <div class="box" style="background-color: #7FFC7F;"> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> </div> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span> <span></span>
</div>
<style> html, body, main { height: 100%; width: 100%; } body { background-color: grey; -moz-user-select: -moz-none; -webkit-user-select: none; -khtml-user-select: none; -o-user-select: none; user-select: none; display: flex; flex-direction: column; align-items: center; } .box { display: flex; flex-direction: column; margin-bottom: 20px; padding: 10px; margin-bottom: 20px; padding: 10px; overflow: hidden; } body>.box { flex: 1 1 0; display: flex; flex-direction: column; width: 400px; max-width: calc(100% - 20px); } .box>span { width: 200%; flex: 0 0 20px; } .box>span:nth-child(2n) { background-color: rgba(0, 0, 0, 0.5); } .box>.box { align-self: stretch; flex: 0 0 200px; }
</style>
<script> window.addEventListener('load', function() { // attacher les scrollbar ScrollBarV(document.querySelector('.box')); ScrollBarV(document.querySelector('.box>.box')); });
</script> <script src='js/9db6924f2cab604eb8c7336b5.js'></script>
<script src='js/f0e61caa5742e9d488421d33a.js'></script>
<script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/138204/hand-1.3.8.js'></script> <script src="js/index.js"></script>
</body>
</html>
Custom scrollbar - Script Codes CSS Codes
/* élément scrollable */
.scrollV { overflow-y: hidden; position: relative;
}
/* wrappper */
.scrollWrapper { position: absolute; height: 100%; width: 100%; z-index: 1; flex: 0 0 auto; margin: 5px; border-radius: 5px; background-color: rgba(0, 0, 0, 0.1); opacity: 0; transition: opacity 0.2s ease-in-out;
}
.scrollWrapper.visible { opacity: 1;
}
.scrollWrapper:hover { opacity: 1;
}
.scrollWrapperV { width: 10px;
}
/* la bar */
.scrollWrapper * { flex: 1 1 auto;
}
.scrollBar { position: absolute; width: 100%; height: 100%; border-radius: 5px; background-color: rgba(100, 100, 100, 0.8); cursor: pointer;
}
Custom scrollbar - Script Codes JS Codes
function ScrollBarV(element) { if (!(this instanceof ScrollBarV)) { return new ScrollBarV(element); } if (ScrollBarV.list.indexOf(element) > -1 || !(element instanceof HTMLElement)) { // si l'élément a déjà une bar de défilement, on stoppe tout console.error('unable to create a new ScrollBarV for',element); return false; } ScrollBarV.list.push(element); // ajout à la liste this.ease = {}; // ajouter les méthodes bindées this.recalc = ScrollBarV.recalc.bind(this); this.onWheel = ScrollBarV.onWheel.bind(this); this.onDragStart = ScrollBarV.onDragStart.bind(this); this.onDragging = ScrollBarV.onDragging.bind(this); this.onDragStop = ScrollBarV.onDragStop.bind(this); this.onSwipeStart = ScrollBarV.onSwipeStart.bind(this); this.onSwipeMove = ScrollBarV.onSwipeMove.bind(this); this.onSwipeStop = ScrollBarV.onSwipeStop.bind(this); this.onMouseEnter = ScrollBarV.onMouseEnter.bind(this); this.onEaseStop = ScrollBarV.onEaseStop.bind(this); this.easing = ScrollBarV.easing.bind(this); // gérer le parent this.scrollElement = element; this.scrollElement.classList.add('scrollV'); this.scrollElement.addEventListener('scroll', this.recalc, false); this.scrollElement.addEventListener('mouseenter', this.onMouseEnter, false); window.addEventListener('resize', this.recalc, false); new MutationObserver(this.recalc).observe(this.scrollElement, {childList: true, attributes: false, characterData: false}); // construction du wrapper this.scrollWrapper = document.createElement('div'); this.scrollWrapper.classList.add('scrollWrapper'); this.scrollWrapper.classList.add('scrollWrapperV'); // construction de la bar this.bar = document.createElement('div'); this.bar.classList.add('scrollBar'); this.scrollWrapper.appendChild(this.bar); // ajout dans le dom this.scrollElement.appendChild(this.scrollWrapper); // lancer le calcul this.recalc(); // ajouter l'event wheel this.scrollElement.addEventListener('wheel', this.onWheel, false); // ajouter l'event drag & drop this.bar.addEventListener('mousedown', this.onDragStart, false); // ajouter l'event swipe this.scrollElement.addEventListener('swipeVstart', this.onSwipeStart, false);
}
ScrollBarV.list = [];
ScrollBarV.show = function() { this.scrollWrapper.classList.add('visible'); if (this.setTimeout) { window.clearTimeout(this.setTimeout); } this.setTimeout = window.setTimeout(ScrollBarV.hide.bind(this), 1000);
};
ScrollBarV.hide = function() { this.scrollWrapper.classList.remove('visible');
};
ScrollBarV.prototype.processing = false;
ScrollBarV.recalc = function() { // afficher la barre ScrollBarV.show.apply(this); this.scrollWrapper.style.display = null; var scrollWrapperComputed = window.getComputedStyle(this.scrollWrapper); // calculer la hauteur de la barre this.scrollWrapper.style.height = this.scrollElement.clientHeight - parseInt(scrollWrapperComputed.getPropertyValue('margin-top'), 10) - parseInt(scrollWrapperComputed.getPropertyValue('margin-bottom'), 10) - parseInt(scrollWrapperComputed.getPropertyValue('padding-top'), 10) - parseInt(scrollWrapperComputed.getPropertyValue('padding-bottom'), 10) + 'px';
/*console.info(this.scrollWrapper, this.scrollElement.clientHeight, parseInt(scrollWrapperComputed.getPropertyValue('margin-top'), 10), parseInt(scrollWrapperComputed.getPropertyValue('margin-bottom'), 10), parseInt(scrollWrapperComputed.getPropertyValue('padding-top'), 10), parseInt(scrollWrapperComputed.getPropertyValue('padding-bottom'), 10));*/ // calculer la position haute en fonction du scroll vertical this.scrollWrapper.style.top = this.scrollElement.scrollTop + 'px'; // calculer la position gauche en fonction du scroll horizontal this.scrollWrapper.style.left = this.scrollElement.clientWidth + this.scrollElement.scrollLeft - (this.scrollWrapper.clientWidth + parseInt(scrollWrapperComputed.getPropertyValue('margin-left'), 10) + parseInt(scrollWrapperComputed.getPropertyValue('margin-right'), 10)) +'px'; // calculer les valeurs de référence pour la partie glissante this.bar.style.top = this.scrollElement.scrollTop * this.scrollWrapper.clientHeight / this.scrollElement.scrollHeight + 'px'; this.bar.style.height = this.scrollElement.clientHeight * this.scrollWrapper.clientHeight / this.scrollElement.scrollHeight + 'px'; // cacher la barre si pas de scroll possible this.scrollWrapper.style.display = (this.scrollWrapper.clientHeight === this.bar.offsetHeight ? 'none' : null);
};
ScrollBarV.onMouseEnter = function() { // afficher la barre ScrollBarV.show.apply(this);
};
ScrollBarV.onWheel = function(event) { var delta = event.wheelDeltaY * -1 || event.deltaY * 40; // chrome / firefox // mauvais axe if (!delta) { return; } // gérer propagation if (!(delta < 0 && this.scrollElement.scrollTop === 0) && !(delta > 0 && this.scrollElement.scrollTop + this.scrollElement.clientHeight === this.scrollElement.scrollHeight)) { event.stopPropagation(); event.preventDefault(); this.scrollElement.scrollTop = this.scrollElement.scrollTop + delta; }
};
ScrollBarV.onDragStart = function(event) { if (this.processing) { console.error('dragging not released'); return; } // interdire un second lancement this.processing = true; // supprimer l'event mousedown this.bar.removeEventListener('mousedown', this.onDragStart, false); // figer l'opacité this.scrollWrapper.style.opacity = 1; // modifier l'apparence du curseur document.body.style.cursor = 'default'; // empêcher la selection de texte accidentelle document.body.style.userSelect = 'none'; document.body.style.MozUserSelect = 'none'; document.body.style["-khtml-user-select"] = 'none'; document.body.style["-webkit-user-select"] = 'none'; document.body.style["-o-user-select"] = 'none'; // initier les valeurs de référence this.scrollTopInitial = this.scrollElement.scrollTop; this.mouseTopInitial = event.clientY; this.ratio = this.scrollElement.scrollHeight / this.scrollWrapper.clientHeight; // ajouter les event pour stopper la popote document.addEventListener('click', this.onDragStop, false); document.addEventListener('dblclick', this.onDragStop, false); document.addEventListener('mouseup', this.onDragStop, false); // ajouter l'event de déplacement document.addEventListener('mousemove', this.onDragging, false);
};
ScrollBarV.onDragging = function(event) { if (!this.processing) { console.error('dragging not allowed'); this.onDragStop(); return; } // calculer l'espace à afficher var mouseTopCurrent = event.clientY; var theoricalScrollTop = this.scrollTopInitial + (mouseTopCurrent - this.mouseTopInitial) * this.ratio; theoricalScrollTop = (theoricalScrollTop > 0 ? theoricalScrollTop : 0); theoricalScrollTop = (theoricalScrollTop < (this.scrollElement.scrollHeight - this.scrollElement.clientHeight) ? theoricalScrollTop : this.scrollElement.scrollHeight - this.scrollElement.clientHeight); this.scrollElement.scrollTop = theoricalScrollTop;
};
ScrollBarV.onDragStop = function(event) { // suprimer l'event de déplacement document.removeEventListener('mousemove', this.onDragging, false); // supprimer les event pour stopper la popote document.removeEventListener('click', this.onDragStop, false); document.removeEventListener('dblclick', this.onDragStop, false); document.removeEventListener('mouseup', this.onDragStop, false); // supprimer les valeurs de référence delete this.scrollTopInitial; delete this.mouseTopInitial; delete this.ratio; // libérer la selection de texte accidentelle document.body.style.userSelect = null; document.body.style.MozUserSelect = null; document.body.style["-khtml-user-select"] = null; document.body.style["-webkit-user-select"] = null; document.body.style["-o-user-select"] = null; // libérer l'apparence du curseur document.body.style.cursor = null; // libérer l'opacité this.scrollWrapper.style.opacity = null; // ajouter l'event mousedown this.bar.addEventListener('mousedown', this.onDragStart, false); // authoriser un nouveau lancement this.processing = false;
};
ScrollBarV.onSwipeStart = function(event) { console.info('onSwipeStart', event); if (this.processing) { console.error('scrolling not released'); return; } // interdire un second lancement this.processing = true; // supprimer l'event swipeHstart this.scrollElement.removeEventListener('swipeVstart', this.onSwipeStart, false); // stopper propagation event.stopPropagation(); // figer l'opacité this.scrollWrapper.style.opacity = 1; // modifier l'apparence du curseur document.body.style.cursor = 'default'; // empêcher la selection de texte accidentelle document.body.style.userSelect = 'none'; document.body.style.MozUserSelect = 'none'; document.body.style["-khtml-user-select"] = 'none'; document.body.style["-webkit-user-select"] = 'none'; document.body.style["-o-user-select"] = 'none'; // initier les valeurs de référence this.lastSwipeY = event.detail.distY; // ajouter l'event pour stopper la popote document.addEventListener('swipeVstop', this.onSwipeStop, false); // ajouter l'event de déplacement document.addEventListener('swipeVmove', this.onSwipeMove, false);
};
ScrollBarV.onSwipeMove = function(event) { if (!this.processing) { console.error('swiping not allowed'); this.onSwipeStop(); return; } var delta = event.detail.distY - this.lastSwipeY; this.lastSwipeY = event.detail.distY; // si bloqué on passe notre tour if ((event.detail.distY < 0 && this.scrollElement.scrollTop === this.scrollElement.scrollHeight - this.scrollElement.clientHeight) || (event.detail.distY > 0 && this.scrollElement.scrollTop === 0)){ return; } // sinon on change le scrolltop this.scrollElement.scrollTop = this.scrollElement.scrollTop - delta;
};
ScrollBarV.onSwipeStop = function(event) { console.info('event.detail.velocity',event.detail.velocity); // si on est pas bloqué if (this.scrollElement.scrollTop !== this.scrollElement.scrollHeight - this.scrollElement.clientHeight && this.scrollElement.scrollTop !== 0) { // calculer distance de freinage théorique var delta = Math.pow((event.detail.velocity * 1000 / 10), 2) / 10; var duration = Math.abs(delta / (event.detail.velocity) * 2); // déterminer point de départ var scrollTopStart = this.scrollElement.scrollTop; // déterminer moment d'arret si espace maximal dépassé if (event.detail.velocity > 0) { delta = delta * -1; } console.info('delta', delta, 'px', 'duration', duration, 'ms'); var scrollTopTarget = this.scrollElement.scrollTop + delta; console.info('scrollTopTarget', scrollTopTarget); // lancer l'animation this.ease.startTimestamp = new Date().getTime(); this.ease.stopTimestamp = this.ease.startTimestamp + duration; this.ease.lastTimestamp = null; this.ease.currentTimestamp = new Date().getTime(); this.ease.velocity = event.detail.velocity; // lancement du freinage this.ease.interval = setInterval(this.easing, 30); this.ease.timeout = setTimeout(function() { console.warn('timed out', new Date().getTime()); this.onEaseStop(); }.bind(this), duration); // arrêter freinage si un event touchstart est détecté this.scrollElement.addEventListener('touchstart', this.onEaseStop, false); this.scrollElement.addEventListener('mousedown', this.onEaseStop, false); } else { console.warn('on est au bout'); } // supprimer l'event de déplacement document.removeEventListener('swipeVmove', this.onSwipeMove, false); // supprimer l'event pour stopper la popote document.removeEventListener('swipeVstop', this.onSwipeStop, false); // supprimer les valeurs de référence delete this.lastSwipeY; // libérer la selection de texte accidentelle document.body.style.userSelect = null; document.body.style.MozUserSelect = null; document.body.style["-khtml-user-select"] = null; document.body.style["-webkit-user-select"] = null; document.body.style["-o-user-select"] = null; // libérer l'apparence du curseur document.body.style.cursor = null; // libérer l'opacité this.scrollWrapper.style.opacity = null; // ajouter l'event swipeHstart this.scrollElement.addEventListener('swipeVstart', this.onSwipeStart, false); // authoriser un nouveau lancement this.processing = false;
};
ScrollBarV.easing = function() { console.info('actuel', new Date().getTime(), 'debut', this.ease.startTimestamp, 'arret', this.ease.stopTimestamp); this.ease.lastTimestamp = this.ease.currentTimestamp; this.ease.currentTimestamp = new Date().getTime(); var t = (this.ease.currentTimestamp - this.ease.startTimestamp) / (this.ease.stopTimestamp - this.ease.startTimestamp); var ratio = easing.easeOutCirc(t); console.info('t', t, 'ratio', ratio); var newScrollTop = this.scrollElement.scrollTop + (this.ease.currentTimestamp - this.ease.lastTimestamp) * -1 * (this.ease.velocity * (1 - ratio)); this.scrollElement.scrollTop = newScrollTop; if (newScrollTop <= 0 || newScrollTop >= this.scrollElement.scrollHeight - this.scrollElement.clientHeight || t >= 1) { this.onEaseStop(); }
};
ScrollBarV.onEaseStop = function(event) { console.info('ease stop', event); // stopper le easing clearInterval(this.ease.interval); clearTimeout(this.ease.timeout); // retirer l'event onEaseStop this.scrollElement.removeEventListener('touchstart', this.onEaseStop, false); this.scrollElement.removeEventListener('mousedown', this.onEaseStop, false);
}
Developer | Anthony Pothin |
Username | Thorien |
Uploaded | January 17, 2023 |
Rating | 3 |
Size | 7,800 Kb |
Views | 4,048 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
Magic table | 8,674 Kb |
Responsive slide | 2,400 Kb |
Form - datetime picker | 6,482 Kb |
A Pen by Anthony Pothin | 4,034 Kb |
Form - checkbox | 3,829 Kb |
Form - form | 3,487 Kb |
Tab bar | 3,423 Kb |
Resizable flexible box | 3,381 Kb |
Demo component | 2,725 Kb |
Flexible accordion | 2,356 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
IE11 Test | Boostnewmedia | 4,998 Kb |
Hamburger Menu Animation | Salmanraza | 2,580 Kb |
Next Word Predictor | Rfalor | 2,776 Kb |
Header Line Issue | Charlie-volpe | 1,768 Kb |
FontAwesome icons with animation | Nicotinell | 2,083 Kb |
CSS3 keyframe onload animation. | Samueljseay | 1,706 Kb |
Pure CSS Menu | Bronsrobin | 3,321 Kb |
A Pen by Xand0r | Xand0r | 1,928 Kb |
About Mazano | Kiti | 2,585 Kb |
Contact | GanNichiHa | 2,514 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!