Vue 2 Sirective for Custom Scrollbar that uses Native Scroll Behavior

About

The first Vue 2 custom scrollbar library that only enhances scrolling instead of reimplementing it with custom scroll behavior. Created by Dominik Serafin.

It uses native scroll events to detect and synchronize scrollbar position. This makes possible to hack into the native events of scrolling element without hassle.

It was built for GGather.com where it plays nicely with a lot of dynamic content changes and most importantly infinite scrolling and drag and drop features. And now after testing, fixes, improvements and added customization options - it’s ready to be shared with the world.

  • Directive instead of a custom component, which saves a lot of headaches.
  • Native scroll events, no jankiness, no hijacking.
  • Simple to use, lightweight & performant.
  • Works in browser and also build (webpack, etc.) environments.
  • Compatible with all major browsers including IE9 and above.
  • Useful customization options.
  • No 3rd party dependencies.
  • Tested in production.

Installation

NPM

npm install vuebar --save

CDN

https://unpkg.com/vuebar

Manual

Download the .js file directly from latest commit and include manually in your project

vuebar.js

Alternative #1: Include in browser

<script src="vuebar.js"></script>

Alternative #2: Include in your build

import Vuebar from 'vuebar';
Vue.use(Vuebar);

Usage

Basic Markup

<div v-bar> <!-- el1 -->
  <div> <!-- el2 -->
    <!-- your scrollable content -->
  </div>
  <!-- dragger will be automatically added here -->
</div>

Markup with example options

<div v-bar="{
    preventParentScroll: true,
    scrollThrottle: 30,
}"> <!-- el1 -->
  <div> <!-- el2 -->
     <!-- your scrollable content -->
  </div>
  <!-- dragger will be automatically added here -->
</div>

How it works

Every Vuebar scrollable content needs to be wrapped in parent element el1 that hides the native browser scrollbar of the second parent element el2 and it also contains the custom scrollbar element (referenced further as dragger) which gets appended automatically on the Vuebar initialization.

New in 0.0.6: Instead of hiding the scrollbar using el1 Vuebar now has a useScrollbarPseudo feature that hides the scrollbar using pseudo element selector ::-webkit-scrollbar. Due to browsers limitations for now it works only on desktop Chrome & desktop Safari at the moment.

The Vuebar internals listen to el2 scroll event and synchronize dragger position when you scroll. And vice versa - when you directly use dragger it listens to mouse events to detect the position of dragger and sets scroll position of el2.

Other than setting the scroll position when you use dragger the Vuebar doesn’t interfere at all with native browser scrolling and you can listen to scroll/wheel/etc. events as you would normally do.

This also means the scroll behavior will remain unchanged. You’ll still be able to use mouse wheel click scrolling or touch scrolling with momentum. It doesn’t try to reimplement the scrolling from scratch like most of similar libraries try (with bad results).

Public methods (experimental & work in progress)

You can access them from your component context: this.$vuebar. Alternatively you can access them from your main Vue instance: Vue.vuebar.

Every method needs to have passed Vuebar scroll container element as the first argument. You can do that easily using $refs.

  • initScrollbar(DOM Element, options)
  • getState(DOM Element)
  • refreshScrollbar(DOM Element, options)
  • destroyScrollbar(DOM Element)

Tips

  • If you want to access internal Vuebar state (like scrollbar height, scrollbar top or even dragger element reference) then you can access _vuebarState property of element 1 with v-bar directive. Or you can use getState method.
  • Element el1 has programmatically added styles position: relative and overflow: hidden so you can’t change them without using !important. But you shouldn’t do it anyway - your scrollbar will break.
  • Element el2 has programmatically added styles overflow-x: hidden, overflow-y: scroll, height: 100%, -ms-overflow-style: scrollbar and width which value depends on browser.
  • If the original browser scrollbar is floated/overlayed (-ms-autohiding-scrollbar, touch devices, etc.) then el2 also has padding-right changed.
  • Similar thing with dragger - it has programmatically added styles position: absolute and height with top that have values in pixels relative to scroll position.

Styling

Every Vuebar element has a child dragger element. That element also has its own child - a dragger-styler element that’s purely there for you to style it any way you want. You can also style the original dragger element - just remember it has position: absolute style always applied and height and top styles dynamically added & changed when scrolling.

Default Style

If you were looking for this library it means you want to style your scrollbars as you want - so Vuebar doesn’t include default styles internally. But if you e.g. want to quickly try or understand how you should style Vuebar scrollbars then below are prepared default styles that you can copy-paste into your project.

.vb > .vb-dragger {
   z-index: 5;
   width: 12px;
   right: 0;
}

.vb > .vb-dragger > .vb-dragger-styler {
   -webkit-backface-visibility: hidden;
   backface-visibility: hidden;
   -webkit-transform: rotate3d(0,0,0,0);
   transform: rotate3d(0,0,0,0);
   -webkit-transition:
       background-color 100ms ease-out,
       margin 100ms ease-out,
       height 100ms ease-out;
   transition:
       background-color 100ms ease-out,
       margin 100ms ease-out,
       height 100ms ease-out;
   background-color: rgba(48, 121, 244,.1);
   margin: 5px 5px 5px 0;
   border-radius: 20px;
   height: calc(100% - 10px);
   display: block;
}

.vb.vb-scrolling-phantom > .vb-dragger > .vb-dragger-styler {
   background-color: rgba(48, 121, 244,.3);
}

.vb > .vb-dragger:hover > .vb-dragger-styler {
   background-color: rgba(48, 121, 244,.5);
   margin: 0px;
   height: 100%;
}

.vb.vb-dragging > .vb-dragger > .vb-dragger-styler {
   background-color: rgba(48, 121, 244,.5);
   margin: 0px;
   height: 100%;
}

.vb.vb-dragging-phantom > .vb-dragger > .vb-dragger-styler {
   background-color: rgba(48, 121, 244,.5);
}

Examples

Other than examples below - this site itself is an example of Vuebar usage. If you look to the right it has a custom white scrollbar that showcases itself pretty nicely.

1. JSFiddle

Download Details:

Author: DominikSerafin

GitHub: https://github.com/DominikSerafin/vuebar

#vuejs #javascript #vue-js

Vue 2 Sirective for Custom Scrollbar that uses Native Scroll Behavior
11.20 GEEK