mdbootstrap / perfect-scrollbar

Minimalistic but perfect custom scrollbar plugin. Get more free components with Material Design for Bootstrap UI Kit (link below)
https://perfectscrollbar.com/
MIT License
352 stars 69 forks source link

Wrongly visible on the left / race condition in scrollbarYRight detection #106

Open hyperknot opened 6 years ago

hyperknot commented 6 years ago

Hi, after a long journey with simplebar and OverlayScrollbars I've finally settled on perfect-scrollbar for a larger project, as that was the only one not messing with the container's styling. It is kind of perfect, really.

One bug I have is that it mistakenly thinks that the scrollbar should be on the left.

What is happening is that scrollbarYRight detection needs to wait a bit, otherwise it gets detected as missing / isNaN / isScrollbarYUsingRight = false.

Problematic part: https://github.com/utatti/perfect-scrollbar/blob/54103fab66ae255ef73aeea57e095385e03c6c01/src/index.js#L119

If I enter:

console.log(railYStyle.right)   -> ''

window.setTimeout(() => {
  console.log(railYStyle.right)  -> '0px'
}, 0)

The first line will output '' while the timeout one will return 0px. Also, 0px is something that should be taken care of, as it's not an integer.

I've seen other issues about left side visibility, I believe they were running into the exact same issue. https://github.com/utatti/perfect-scrollbar/issues/784

I cannot make a fiddle out of it, as in simple example the race condition doesn't happen.

Ugly workaround:

.ps__rail-y {
  left: auto !important;
}
andrey-hohlov commented 6 years ago

The same problem with Vue directive. Looks like Vue.nextTick() helps.

import Vue from 'vue';
import PS from 'perfect-scrollbar';

const cache = new WeakMap();

export default {
  bind(el, binding) {
    if (typeof window === 'undefined') return;

    const defaults = {
      wheelPropagation: true,
      suppressScrollX: true,
    };

    Vue.nextTick(() => {
      const ps = new PS(el, Object.assign(defaults, binding.value));
      cache.set(el, ps);
    });
  },
  update(el) {
    const ps = cache.get(el);
    if (ps) {
      ps.update();
    }
  },
  componentUpdated(el) {
    const ps = cache.get(el);
    if (ps) {
      ps.update();
    }
  },
  unbind(el) {
    const ps = cache.get(el);
    cache.delete(el);
    if (ps) {
      ps.destroy();
    }
  },
};
DzmVasileusky commented 5 years ago

+1 Came here from ngx-scrollbar issues https://github.com/zefoy/ngx-perfect-scrollbar/issues/149 I have created stackblitz (Angular engine but the same scrollbar in it) https://angular-wapzv9.stackblitz.io

If the container is originally empty scrollbar will be on the left even after loading data into it and updating.

On top of it there is a bug that scrollable area become expanded and you can scroll much more than really occupied space.

despian commented 5 years ago

+1 Also having problems with this.

spade69 commented 5 years ago

+1 haha. though, ugly workaround, but it works!

mwinata94 commented 5 years ago

+1, another workaround is by flipping the text direction of the container, and then flip it back in the container items:

container.ps {  
  direction: rtl;  
}  
container > .item {  
  direction: ltr;  
}  

the railling is under div tag, so avoid doing:

container > div {  /* dont do this */
  direction: ltr;  
}
fkranenburg commented 5 years ago

+1 also having this problem where the ugly workaround works perfect!

supersnager commented 4 years ago

On top of it there is a bug that scrollable area become expanded and you can scroll much more than really occupied space.

Try this: https://github.com/mdbootstrap/perfect-scrollbar/issues/920

handhikadj commented 2 years ago

On top of it there is a bug that scrollable area become expanded and you can scroll much more than really occupied space.

Try this: https://github.com/mdbootstrap/perfect-scrollbar/issues/920

the link is dead

hakimio commented 2 years ago

@handhikadj Try the following CSS fix:

/* Fix for perfect scrollbar appearing on left instead of normal right position */
.ps__rail-y {
    right: 0 !important;
    left: unset !important;
}
.ps__rail-x {
    top: unset !important;
    bottom: 0 !important;
}
handhikadj commented 2 years ago

@handhikadj Try the following CSS fix:

/* Fix for perfect scrollbar appearing on left instead of normal right position */
.ps__rail-y {
    right: 0 !important;
    left: unset !important;
}
.ps__rail-x {
    top: unset !important;
    bottom: 0 !important;
}

is this better than the OP's workaround? thanks anyway

hakimio commented 2 years ago

Pretty much the same.