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

scroll bar keeps scrolling down exceeding contents length #51

Open shubhcosmos opened 4 years ago

shubhcosmos commented 4 years ago

Make sure these boxes are checked before submitting your issue -- thank you!

issue no 756 this did not fix the issue , I have latest changes but still it does not works

kfeng0806 commented 4 years ago

Since 1.4.0 update to 1.5.0 i also facing this problem

GuichiZhao commented 4 years ago

@shubhcosmos Will it be fixed in future release?

shubhcosmos commented 4 years ago

try this fix amd the root cause it works fine

Issue is when you keep scrolling top attribute of ps--rail-y div keeps adding up . So the content height of container div keeps increasing .

in this Fix I have checked that dont increase the top property when top+ innerheight is greater than scroll height

perfect-scrollbar\dist\perfect-scrollbar.esm.js

function updateCss(element, i) {

line 465 onwards

// shubh if(!(element.scrollTop + window.innerHeight >= element.scrollHeight)) { set(i.scrollbarYRail, yRailOffset); }

set(i.scrollbarX, { left: i.scrollbarXLeft, width: i.scrollbarXWidth - i.railBorderXWidth, });

set(i.scrollbarY, { top: i.scrollbarYTop, height: i.scrollbarYHeight - i.railBorderYWidth, });

statyan commented 4 years ago

The root cause of the issue it changes in update-geometry: This code

i.containerWidth = element.clientWidth;
i.containerHeight = element.clientHeight;

was replaced with this one:

const rect = element.getBoundingClientRect();
i.containerWidth = Math.ceil(rect.width);
i.containerHeight = Math.ceil(rect.height);

getBoundingClientRect does not take into account borders on the container element. So if you have the borders - I'll get the bug with infinite scroll.

kfeng0806 commented 4 years ago

The root cause of the issue it changes in update-geometry: This code

i.containerWidth = element.clientWidth;
i.containerHeight = element.clientHeight;

was replaced with this one:

const rect = element.getBoundingClientRect();
i.containerWidth = Math.ceil(rect.width);
i.containerHeight = Math.ceil(rect.height);

getBoundingClientRect does not take into account borders on the container element. So if you have the borders - I'll get the bug with infinite scroll.

I have issue with horizontal scroll on touch device but container without border, it scroll exceed the container width

dexcell commented 4 years ago

I had to rollback to 1.4.0 because of this issue.

mattonit commented 4 years ago

what are the steps to reproduce this issue?

Dev1lDragon commented 4 years ago

here representation of bug perfect scrolbar bug 1.5.0

also recreated on X

kfeng0806 commented 4 years ago

it probably cause by rails, rail-y on mouse scroll and rail-x happend on touch device

supersnager commented 4 years ago

Please try my fix mdbootstrap/Tailwind-Elements#934 for this issue

supersnager commented 4 years ago

Just added one more fix, after testing in some different cases.

pushpendersingh97 commented 4 years ago

This issue is easily reproducible in IE, with resolution of 1366 *768. When a container have a height of 456 then it is going continuously downwards.

supersnager commented 4 years ago

@pushpender98 have you tested it with my fix?

pushpendersingh97 commented 4 years ago

@supersnager yes it is still coming when the parent div have height in points.

shubhcosmos commented 4 years ago

Try my fix above and the reason i debugged it , its tested and working fine on dev and prod

kfeng0806 commented 4 years ago

@supersnager thanks for fix, i tried your fix on master but the issue still exists

Dev1lDragon commented 4 years ago

@kfeng0806 for fix in master you need to rebuild dist files

kfeng0806 commented 4 years ago

@Dev1lDragon Thanks for the tips, after rebuild it proves the fix works :) And thanks @supersnager again, you are life saver 👍

pushpendersingh97 commented 4 years ago

I have tried it at my end, and this issue is still coming in the IE. Please have a look upon it.

image

supersnager commented 4 years ago

@pushpender98 Please provide an example on jsfiddle or as github project, i will try to fix it.

pushpendersingh97 commented 4 years ago

@supersnager , This issue is occuring in IE only at some specific version. So not able to reproduce on jsfiddle. image

supersnager commented 4 years ago

@pushpender98 Sorry, but i can't help if it's not possible to reproduce this issue

Dev1lDragon commented 4 years ago

@pushpender98 try to find in your compiled js file Math.ceil and after that Math.round if you find first you don't compiled js to work.

totszwai commented 4 years ago

This happens even with v1.3.0, @dexcell I doubt rolling back to 1.4.0 would fix it? Unless this is yet another regression issue after 1.4.0?

supersnager commented 4 years ago

Is it possible to make stable release with this fix?

Borlu commented 4 years ago

If you are adding border to div element like me, please you don't do it. I don't know root cause but when you are remove border outside of div element the problem is solving.

fnfilho commented 4 years ago

I also have this issue. Happening on Chrome 81. Outside div does not have border, nor inside one.

supersnager commented 4 years ago

I also have this issue. Happening on Chrome 81. Outside div does not have border, nor inside one.

@fnfilho Problem exists with or without my fix?

fnfilho commented 4 years ago

I wasn't able to test it because I am using it through another dependency for React. Would need the stable release to force npm to use that

invisor commented 4 years ago

1.5 is really buggy. Rolled back to 1.4

NaturalDevCR commented 4 years ago

Rolling back to 1.4 worked for me, hopefully there will be an update with the fix

green-katerin commented 4 years ago

I have the same problem, you can see it here https://jsfiddle.net/swv0e9ra/

supersnager commented 4 years ago

@bochkareva Please try last commit from master. Unfortunately there is no stable release yet with this fix

green-katerin commented 4 years ago

@supersnager thanks, I fixed this in my project by moving "border" to another element

mrfrigerio commented 4 years ago

try this fix amd the root cause it works fine

Issue is when you keep scrolling top attribute of ps--rail-y div keeps adding up . So the content height of container div keeps increasing .

in this Fix I have checked that dont increase the top property when top+ innerheight is greater than scroll height

perfect-scrollbar\dist\perfect-scrollbar.esm.js

function updateCss(element, i) {

line 465 onwards

// shubh if(!(element.scrollTop + window.innerHeight >= element.scrollHeight)) { set(i.scrollbarYRail, yRailOffset); }

set(i.scrollbarX, { left: i.scrollbarXLeft, width: i.scrollbarXWidth - i.railBorderXWidth, });

set(i.scrollbarY, { top: i.scrollbarYTop, height: i.scrollbarYHeight - i.railBorderYWidth, });

For me, this solution worked like a charm! Thank you @shubhcosmos

ZinoKader commented 4 years ago

For those who the above fixes didn't work - my problem was setting an element's padding in the scroll container using em/rem - which perfect-scrollbar couldn't account for. The fix was to simply use px instead.

cinnabarcaracal commented 4 years ago

I use react-perfect-scrollbar and this issue kept coming up. Here is a horrid little workaround I came up with to give us access to @supersnager's fix without waiting for both projects to put out new releases.

...

<PerfectScrollbar
  containerRef={ref => {
              if (ref) {
                // https://github.com/mdbootstrap/perfect-scrollbar/pull/934/files
                // injecting a fix for this issue
                ref._getBoundingClientRect = ref.getBoundingClientRect;

                ref.getBoundingClientRect = () => {
                  const original = ref._getBoundingClientRect();

                  return { ...original, height: Math.round(original.height) };
                };
              }
  }}
>
{content}
</PerfectScrollbar>

...
supersnager commented 4 years ago

@cinnabarcaracal Good job! I'll try it, i also use react-perfect-scrollbar.

abdulmatinsanni commented 4 years ago

I use react-perfect-scrollbar and this issue kept coming up. Here is a horrid little workaround I came up with to give us access to @supersnager's fix without waiting for both projects to put out new releases.

...

<PerfectScrollbar
  containerRef={ref => {
              if (ref) {
                // https://github.com/mdbootstrap/perfect-scrollbar/pull/934/files
                // injecting a fix for this issue
                ref._getBoundingClientRect = ref.getBoundingClientRect;

                ref.getBoundingClientRect = () => {
                  const original = ref._getBoundingClientRect();

                  return { ...original, height: Math.round(original.height) };
                };
              }
  }}
>
{content}
</PerfectScrollbar>

...

You're a legend. Copied and pasted your solution, and it worked straight out of the box. 😁

mstys commented 4 years ago

Some improvements - for horizontal scroll add original.width and for firefox users better to use Math.floor ;)

  <PerfectScrollbar
        containerRef={(ref) => {
          if (ref) {
            // https://github.com/mdbootstrap/perfect-scrollbar/pull/934/files
            ref._getBoundingClientRect = ref.getBoundingClientRect;

            ref.getBoundingClientRect = () => {
              const original = ref._getBoundingClientRect();

              return {
                ...original,
                width: Math.floor(original.width),
                height: Math.floor(original.height),
              };
            };
          }
        }}
      >
        {this.props.children}
      </PerfectScrollbar>
efreibe commented 4 years ago

In my case, I was fighting with this behaviour until I've discovered that the 1px border was the culprit.

supersnager commented 4 years ago

I have tested solution proposed by @cinnabarcaracal and its's almost perfect but... getBoundingClientRect() function returns object of type DOMRect, which cannot be copied by object spread operator like this {...original}. Its explained here: https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#Notes Thus object properties should be copied manually. Because overwitten getBoundingClientRect can be used also for other calculations in client code (e.g. i'm using it to do some calculations to keep scroll at the bottom of chat messages list) we can't omit properties other than witdh an height.
So all properties returned from getBoundingClientRect() must be copied.
Also, someone for some reason may want to have access to the original sizes, so it can be added as additional properties to returned object.

<PerfectScrollbar
  containerRef={ref => {
              if (ref) {
                // https://github.com/mdbootstrap/perfect-scrollbar/pull/934/files
                // injecting a fix for this issue
                ref._getBoundingClientRect = ref.getBoundingClientRect;

                ref.getBoundingClientRect = () => {
                  const original = ref._getBoundingClientRect();

                  return {
                    bottom: original.bottom,
                    left: original.left,
                    right: original.right,
                    top: original.top,
                    width: Math.round(original.width),
                    _width: original.width, 
                    height: Math.round(original.height),
                    _height: original.height, 
                    x: original.x,
                    y: original.y
                  };
                };
              }
  }}
>
{content}
</PerfectScrollbar>

BTW As @efreibe notices firefox behaves differently. For me Math.floor doesn't work, so im searching for solution.

viaativaweb commented 3 years ago

Making sure the scroll element has position: relative fixed the problem for me

totszwai commented 3 years ago

Sadly, we ended up ditching perfect-scrollbar as it gave us more trouble... as Internet Explorer is now obsolete and the new Edge is using Chromium, there is much less need to use perfect-scrollbar.

The following vanilla CSS does pretty much the same thing.

// W3C standard/Firefox-only
* {
    scrollbar-width: thin;
    // https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-color
    scrollbar-color: #d2d2d2 #eeeeee;
}

// Chrome/Edge/Safari
*::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}
*::-webkit-scrollbar-thumb {
    background-color: #d2d2d2;
}

*::-webkit-scrollbar-track,
*::-webkit-scrollbar-corner {
    background: #eeeeee;
}
lackneets commented 3 years ago

I found my container has border-top 1px, problem solved after removing it.

StrikeAgainst commented 3 years ago

Bump, when will this make it into a stable release?

juliandm commented 3 years ago

For react users having this issue, i switched to with success https://github.com/malte-wessel/react-custom-scrollbars

anas-appiskey commented 3 years ago

For react users having same issue use position : static, will solve this

<ScrollBar style={{ position: "static", height: "as per your choice" }}>

dongloo commented 3 years ago

Set height: auto or some px !important for element, this working!

hamzahoda commented 3 years ago

For react users use version 1.4 .0 . It works perfectly npm i perfect-scrollbar@1.4.0