Empty scrollbar appears with no overflow

Viewed 484

I want to know if there's a clean way to "reset" the scrollbar.

In the series of images below, you can see how the same-sized body and HTML differ by having a scroll bar and not.

Interestingly, the scrollbar is not present in the final image, just the region where the scrollbar scrolled persists.

I'd prefer to not set a max-height attribute of 599px to avoid the overflow. I'm looking to anyone who's seen this bug and knows of a nice way to reset the scrollbar area.

1. The first image is expanding the chrome extension to its maximum 600px height.

Initial Display (no overflow)

2. The second image is expanding the tables to overflow the 600px height, producing a scroll bar.

Extend table for overflow

3. The third image is collapsing the table and reverting the display to the original 600px height; however, now there exists an empty "scroll field"?

Collapse table but overflow appears

1 Answers

Using requestAnimationFrame — Updated

By using requestAnimationFrame(), the scrollbar is refreshed exactly on the DOM repaint:

function scrollRefresh(element) {
    // initial overflow attribute
    element.style.overflow = "auto";
    requestAnimationFrame(() => {
        // final overflow attribute
        element.style.overflow = "overlay";
    });
}

A benefit of using requestAnimationFrame is the scrollbar never changes to the user; instead, the DOM repaints it seemlessly. This method is much more smooth and efficient than the setTimeout() alternative.



Using setTimeout

A function that forces the DOM to refresh the scrollbar will work:

function scrollRefresh(element) {
    // initial overflow attribute
    element.style.overflow = "auto";
    setTimeout(() => {
        // final overflow attribute
        element.style.overflow = "overlay";
    }, 17); // 17 ms timeout
}

Two things of note in this solution:

  1. The overflow switching must include the auto overflow attribute. Beginning with auto or overlay does not matter; it is, however, necessary that the final overflow attribute is different from the initial.
  2. The timeout is proportional to success. A timeout of 0 ms won't work, while a timeout of 5 ms will work around 30%. A timeout of 20 ms worked consistently for me.

I believe the timeout is related to the DOM refresh rate. From a quick search, it's around 60 fps (or 16.6̅ ms), so a 20 ms is more than enough. A timeout of 17 ms should refresh slowly enough for the DOM to always render the overflow change.



Here's a demonstration of the function working:

working overflow refresh

I want to thank @lastr2d2 for their comment, as it helped me find a solution.

Related