KingSora / OverlayScrollbars

A javascript scrollbar plugin that hides the native scrollbars, provides custom styleable overlay scrollbars, and preserves the native functionality and feel.
https://kingsora.github.io/OverlayScrollbars
MIT License
3.78k stars 214 forks source link

Ability to specify scrollbar visibility per axis #590

Closed Zach-Haddad closed 9 months ago

Zach-Haddad commented 9 months ago

Is your feature request related to a problem? Please describe. Hello -- love the project! Half bug/half feature request here. We have a specific use case to have an element that is only scrollable on the y-axis with click-and-drag scrolling and NOT by way of normal (scroll wheel) scrolling. We do not want the x-axis scrollbar to display at all. See stackblitz example here.

The problem is, we need to set visibility to visible in the setup for the y-axis to render, but this also renders the x-axis. Setting visiblity to auto hides both axes here, since overflow.y is marked hidden. If I try to hide the x-axis by way of CSS, the final product doesn't look ideal since the 'corner` element still renders, and the y-axis has that bit of offset at the bottom. Is there an existing workaround to this issue?

Describe the solution you'd like Ideally, we'd like to be able to specify visibility per axis. For example:

OverlayScrollbars(scrollable, {
  overflow: {
    // Prevent natural scrolling.
    y: 'hidden',
  },
  scrollbars: {
    visibility: { x: 'auto', y: 'visible' },
    theme: 'os-theme-dark',
  },
});

And then adjust the setup logic here (and maybe split up setScrollbarVisibility for each axis) to read the separate values from the config if given, otherwise retain the same behavior for backwards compatibility.

Describe alternatives you've considered Happy to hear any existing workarounds for this!

Additional context N/A, but please let me know what other info you need. Also happy to start up a PR for this. Thank you!

Zach-Haddad commented 9 months ago

Quick update:

Was able to get this looking better by doing the following -- set overflow.x and overflow.y to hidden, visibility is visible. And apply the following styles:

.os-scrollbar-horizontal
  display: none
.os-scrollbar-vertical
  bottom: 0 !important
KingSora commented 9 months ago

Good day @Zach-Haddad :)

I do understand your need of specifying the visibility per axis, but I believe that in reality only a tiny fraction of users would really need this feature. Thats the reason I'm a bit hesitant to implement it since from a technical perspective it seems to be pretty straight forward.

I believe I've found a nice workaround for your case which can be achieved with the updated event and a specific set of options:

OverlayScrollbars(scrollable, {
  overflow: {
    x: 'hidden',
    y: 'scroll',
  },
}, {
  updated: (instance) => {
    instance.elements().scrollOffsetElement.style.overflow = 'hidden'
  }
});

Here is a demo based on your example: https://stackblitz.com/edit/typescript-k5zgj2?file=index.ts

With this config the horizontal scrollbar will never render because the overflow is hidden, and the vertical scrollbar would only render when there is an overflow (which you need to be able to scroll anyway). With the updated event you set the overflow property of the scrolling element to hidden which prevents the native scrolling functionality.

If you don't want to set the event all the time you initialize OverlayScrollbars you could also create an plugin which adds this event for you.

Zach-Haddad commented 9 months ago

Hey @KingSora -- no worries, kinda figured it would be a very narrow edge case 😄. The above workaround is great and I was able to port it over to our Vue component. A lot cleaner imo than the style workaround. Thanks so much!

KingSora commented 9 months ago

@Zach-Haddad Glad I could help!