Perfect-scrollbar: IE issue: Jumpy scrolling in IE

Created on 19 Jun 2014  ·  42Comments  ·  Source: mdbootstrap/perfect-scrollbar

I confirmed this in the very latest IE too.
Sorry to IE users. This is a bug and there'll be some patches for this issue.

56 and #118 are redirected to this issue.

Any contribution from anyone will be welcomed.

Thank you.

wontfix bug

All 42 comments

It seems like there is some delay between scrolling and updating the scrollbars positions, causing a jumpy effect. The workaround that I have used is to isolate both scrollbars, and not putting them in the scrollable area. Note that updating the positions is not necessary with this set up. I'm looking forward to see a solution, as my workaround breaks the design philosophy of Perfect Scrollbar.

Is there a test-page that demonstrates this bug?
If so, I'd like to look into this ... otherwise, i'll make a test myself ;-)

You may be able to see this everywhere using the plugin, as I heard, so you can try examples in repo.

A simple example with a lot of text: http://plnkr.co/edit/vJjyq8JeUFLD1fzM2LRj?p=preview
Both IE9 and IE11 have this jumpy scrolling issue

I took a quick look, don't see how to solve it without getting the rails out of the scroll container.
Tried a few options, just didn't find a way to solve it without doing structural changes...

any news on this issue? this is an awesome plugin but i have to get it working on IE 11...

Hi, I stopped looking for a solution.

It is a known glitch in internet explorer ... the solution lies in
modifying the html structure which breaks with the philosophy of the
scrollbar.

I switched to http://manos.malihu.gr/jquery-custom-content-scroller
since my current project is nearing completion and Internet Explorer is
not to be ignored for the target audience.

On 2015-01-13 15:55, doronsever wrote:

any news on this issue? this is an awesome plugin but i have to get it working on IE 11...

Reply to this email directly or view it on GitHub [1].

Links:

[1]
https://github.com/noraesae/perfect-scrollbar/issues/160#issuecomment-69755772

Hi,

I have used perfect scrollbar in my kendo grid content on both axis. It is appearing fine but its flickering while scrolling. It seems like there is some delay between scrolling and updating the scrollbars positions, causing a jumpy effect.
Please reply.

Thanks

Hiya,

I'm really sorry for the inconvenience here. Because of my shortage of environment and time, the process hasn't be done quickly so far. I'll try to do it asap. Any help will be really appreciated.

Cheers,

Thanks for @larvanitis's suggestion, I've installed IE VM. Now this issue is the highest priority, and I'm working on it. It's kinda tricky and I'm not sure if I can fix it very quickly, but I'll do my best.

Cheers guys!

Okay guys, I narrowed down the reason. Please refer to the following fiddle.

http://jsfiddle.net/js5hwjjt/

As you can see in the script, we change scrollTop and top properties at the same time. It means, the red square shouldn't blink, because both properties are updated in the same event cycle. As expected, in many major browsers such as Chrome, Safari or FF, it doesn't blink.

But well, in IE, it blinks, which eventually means that IE doesn't update the window completely during a JS context. It is nothing but a wrong behaviour of the browser itself.

Anyway, to fix the issue, we should modify the whole update logic of the plugin, as IE is totally broken in such a simple example. I'm sorry to frustrate you guys, but it may take longer than I thought it would.

Cheers 😂

+1 This is a major blocker for it to be used in production, otherwise everything works very nice.

I've been playing around a bit. What seems to be the issue is that you are changing the scroll top, and then changing the styling. I have no idea how IE works, but I guess it performs the redrawing when scroll top changes, and freezes the rendering until that has finished, before applying other style changes.

A solution I found is simply changing the order. First change the top styling, afterwards change the scrollTop: http://jsfiddle.net/DanielApt/uc8defz0/

Secondly I briefly explored using CSS transform, as they use the GPU, which could address the repainting. I tried that here, but actually there's a slight shaking (not blinking) effect. http://jsfiddle.net/DanielApt/jpcqpvg9/

I think therefore the first option works better, and is less big of a change. I have only tested the jsfiddles with IE9, and I'm not sure if this works when applied to the plugin itself.

Just tested this in the plugin itself. Basically I called updateGeometry() before changing the scrolltop.

It seems to _slightly_ improve the behaviour in IE (especially in IE9). I'm not seeing as much flashing, but when scrolling it still makes large jumps when scrolling.

I have a suspicion that the jumping behaviour is a performance issue in IE, due to the many reads and writes.

Every time the user scrolls we read the scrollTop which causes a browser repaint. Afterwards we change the layout, which again calls a repaint.

This might be a useful resource to tackling the issue http://www.html5rocks.com/en/tutorials/speed/animations/. It mentions using requestAnimationFrame, which sadly would not address IE9, but it could address IE10 and IE11.

Also in general the above article has a few valuable lessons, and it's mostly based around scrolling performance.

I've had the chance to spend a bit more time on this. The problem is actually two-fold:

  1. All scrolling causes flickering of bars, especially when a large amount is scrolled.
  2. Mousewheel scrolling is in large jumps.

I haven't yet pinpointed the cause of issue no.1, but I do know why issue no. 2 is happening.

Each browser exposes its mousewheel scroll delta in a different way. IE's scroll delta will _always_ be 120 or -120. What changes is how often it fires, not the value of the scroll delta itself. We'd need to normalise the scroll delta to get a more consistent scroll and smoother experience. Somebody has attempted to normalise the scroll delta in this jsbin, and a brief test showed it scrolling smoothly in IE11.

I think _Issue 1_ is more important to address, as this affects more than just mousewheel scrolling, and is more noticeable.

Ok, so here's a solution for _Issue 1_: don't position the scrollbar relative to the container.

That would mean that—_gasp_—we'd use fixed positioning to address it. I've only been testing it with mousewheel, but it's looking promising so far.

@noraesae have you in the past explored using fixed positioning? What were your reasons for doing it / not doing it?

Actually I've once thought about it. But what if the container moves out of
the display? Because it's fixed position, the scrollbar will remain in the
same position. So I thought it wasn't a good solution and abandoned it.

The other thought is, as you said, remove the scrollbars from the container
and append them just next to it, but use the other positionings to place
them in the same position as they currently display.

Anyway, it looks quite obvious that to fix the IE issue, we need to rethink
how the scrollbar works :(

On Saturday, April 11, 2015, DanielApt [email protected] wrote:

Ok, so here's a solution for _Issue 1_: don't position the scrollbar
inside the element.

That would mean that—_gasp_—we'd use fixed positioning to address it.
I've only been testing it with mousewheel, but it's looking promising so
far.

@noraesae https://github.com/noraesae have you in the past explored
using fixed positioning? What were your reasons for doing it / not doing it?


Reply to this email directly or view it on GitHub
https://github.com/noraesae/perfect-scrollbar/issues/160#issuecomment-91593570
.

At least there's some good news then… I've got it working with fixed positioning, and when the browser scrolls it repositions them. You can check it out on my fork https://github.com/DanielApt/perfect-scrollbar/tree/issue-1-fix

Wow, it looks promising. I'll definitely try it, but I may take a rest today as it's 1.30am here :crescent_moon:
Great work!

I've just tested and it looks like the best idea to resolve this issue. We may also be able to make the logic even simpler using the rect information.

It works fine, until transforms are used. The use of getBoundingClientRect() does not take transform in consideration. Many people use translate3d(0,0,0) to enable GPU rendering, but that breaks the scrollbars.

Also because the scrollbars are now in a sense “not attached” to their element anymore they sort of move-freely in the z-index space. This means that when you hover over a .ps-container you'll see many positioned elements flicker. This is because the usage of opacity forces it to be placed in a new z-index (discussion) (example).

In many basic projects it works fine, but the fixed positioning option does not play nicely in big scenarios. I would prefer to use jScrollPane's approach, where they wrap the content in a container.

What I suggest is the following

<div class="content">
    Lorem ipsum dolor sit amet...
</div>

after Ps.initialize()

<div class="content">
    <div class="ps-content">
        Lorem ipsum dolor sit amet...
    </div>
    <div class="ps-scrollbar-x-rail">
        <div class="ps-scrollbar-x"></div>
    </div>
</div>

Just finished quite a bit of work, where the content is moved around in its own container. Still need to work on properly getting RtL and opposite side scrollbars to work. First test in IE9 show it works, and we're not seeing any flickering.

https://github.com/DanielApt/perfect-scrollbar/commits/solution-2

Will do some more testing and dev work tomorrow hopefully.

I've actually noticed the solution before, but there are some reasons I cannot accept this way of change.

  1. It modifies the original DOM. What if there's a selector like content>h1 used in a user's code? Actually, it's not a big deal if we can inform the user to take the change into account. Nevertheless, I'm afraid I'd like to make the plugin not to modify the original DOM structure.
  2. I'd not like to use top and left positioning to scroll the element. I'd like to use the native scrollTop and scrollLeft. It's kind of the main goal of the plugin, so i'm really sorry, but I can't accept this change.

However, I've just come up with an idea that, how about using the fixed positioning, but only for IE? Or we may be able to come up with another idea which we can just apply for IEs. I think it's too much to modify the original code base so much only to support IEs.

Anyway, I really appreciate your work. If you have something to discuss, please feel free to tell me :+1:

BTW, I've merged .editorconfig. Thanks!

No worries, in that case we stick with the fixed position, we'll just have to warn about using transforms on the element or any of its parents.

Also I'll find a fix for the opacity flicker, probably by using rgba() instead of opacity.

PS: Just realised, there could also be a hybrid of the offered ideas:

We could move content in to .ps-content and adjust that elements scroll top. Then all positioning is still relative to the actual element, _and_ we're still using scrollTop.

@noraesae I would consider the solution using the modified DOM. I know its not at technically beautiful buts its practical and does the job. I would not be worried about the styling issue. Thats sort of thins happens ALL THE TIME in JS project where templating engines require extra markup. Also, awesome work @DanielApt for taking the time to look into this :) #2cents

@andri, DOM modifying is not so practical – visualization would change after scrollbar activation (consider all the existing projects, clean projects and projects with scrollbar selection option) and behaviour would change as well (event selectors would change). I appreciate Jun's will to find out a better solution.

@zomp, yeah I guess its hard to go that route this late in the game.

Guys... there is any progress at this issue?

Not from my side… haven't had the chance to look further in to it. Not sure if @noraesae has had the chance to look in to it.

Imho they're two options:

  1. Modify the dom and put the content in a container, and scroll that.
  2. Find a solution to IE's scrolltop changing and the scrollbar's positioning happening in two paints instead of one.

The usage of fixed positioning doesn't work when we put it in product.

_Option 1_ works, but the performance goes downhill.
_Option 2_ would be nicer, and it respects the core of the library, but I've simply not found any solution to address this.

Modifying the dom is not a good idea IMO. It doesn't play well with a lot of things. In our project, perfectScroll is actually the only scroll we can use because it doesn't touch the DOM. All the others just break the layout in a fashion that can't be fixed.

Just a small note, that I don't see this problem in Microsoft Edge on Windows 10

Until there's an official fix, I'll be more than happy to use the forked version by @DanielApt.
Daniel, is there a compiled .js anywhere :-) ?

@martinstender I had two approaches, both with their own issues. Which one did you want to try?

Fork 1 uses fixed positioning. Buggy when elements use css transforms.
Fork 2 wraps content in .ps-container. Performance goes down hill.

The forks won't be able to have the compiled js files, as the /dist directory will be ignored. The easiest way to get the compiled files is to download the fork and run gulp

Great, thank you - I'll give #2 a shot and see how it performs :-)
(Got the gulp working ... was new to that :-)

Since I really like perfect-scrollbar and all others (tried about 5 of them) have many issues, I just detected IE and went with the perfect-scrollbar only on browsers that are not IE and only desktop (device.js) otherwise the overflow auto takes over. IE just won't be as pretty, but it won't be jumpy.


// detect IE
var IEversion = detectIE();

if (IEversion !== false) {
  document.documentElement.className += " msie"
} 



/**
 * detect IE
 * returns version of IE or false, if browser is not Internet Explorer
 */
function detectIE() {
  var ua = window.navigator.userAgent;

  // test values
  // IE 10
  //ua = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)';
  // IE 11
  //ua = 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko';
  // IE 12 / Spartan
  //ua = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0';

  var msie = ua.indexOf('MSIE ');
  if (msie > 0) {
    // IE 10 or older => return version number
    return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
  }

  var trident = ua.indexOf('Trident/');
  if (trident > 0) {
    // IE 11 => return version number
    var rv = ua.indexOf('rv:');
    return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
  }

  var edge = ua.indexOf('Edge/');
  if (edge > 0) {
    // IE 12 => return version number
    return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
  }

    // other browser
  return false;
}

if ($('html').hasClass('desktop') && !$('html').hasClass('msie')) {
  /* perfect-scrollbar v0.6.5 */
  !function ... SCRIPT GOES HERE minified

  $(".selector").perfectScrollbar({ });
  $(".selector").perfectScrollbar('update');
   $('.selector').css('overflow', 'hidden');     

} // end if desktop and not IE any version

CSS

.selector {
   overflow-y: scroll;
   -webkit-overflow-scrolling: touch;
  -ms-overflow-style: -ms-autohiding-scrollbar; 
   -ms-overflow-style: scrollbar;
}

html.desktop .selector {
   overflow:auto;
  -ms-overflow-style: scrollbar;
}

Might be worth looking at gemini scrollbar as they use a similar approach, and change the scrollTop instead of a relative positioning or transform hack.

Testing in IE9 I don't see the jumpy behaviour.

I'd like to conclude this issue as it's resolved in Edge. I guess the answers suggested in this thread are helpful to address the issue, and users can even use other plugins for old IEs. Therefore, I label this issue wontfix. You can surely discuss further and suggest other solutions, though.

One thing that I noticed and I remember fixing some issues on IE11 was that the css has the IE10 friendly:

-ms-touch-action: none;     

But not the unprefixed version supported in IE11:

touch-action: none;

Mentioned here: https://github.com/noraesae/perfect-scrollbar/issues/374

Was this page helpful?
0 / 5 - 0 ratings