Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usage with Flexbox and VirtualList #49

Closed
yellowsix opened this issue May 29, 2018 · 7 comments
Closed

Usage with Flexbox and VirtualList #49

yellowsix opened this issue May 29, 2018 · 7 comments

Comments

@yellowsix
Copy link

I have a case that works fine in Firefox, but not in Chrome. Below I have tried to make a little sample of the case -- the real case it is taken from is a fixed-position navigation tree on the left side of a page. Clicking on a node in the tree expands children. When the tree gets too tall, a scrollbar should appear. This works fine in Firefox but not in Chrome.

Example HTML:

<div style="display:flex;flex-flow:column nowrap;width:200px;position:fixed;z-index:1;top:300px;left:0;background:darkred;color:white;height:calc(100vh - 300px);">
    <div style="flex-shrink:0;padding:20px;">
        Some Stuff
    </div>
    <div id="testScroll" style="flex-grow:1;margin:10px 0 30px 0;border-top:1px solid white;border-bottom:1px solid white;">
        <div id="dynamicContent">
            <div>FIRST THING</div>
            <div>A thing</div>
            <div id="interestingThing">Click this thing</div>
            <div id="extraStuff" style="display:none;">
                <div style="height:700px">Another Tall Thing</div>
            </div>
            <div style="height:500px;">A Tall Thing</div>
            <div>LAST THING</div>
        </div>
    </div>
</div>

Example js:

const scrollbar = OverlayScrollbars(document.getElementById("testScroll"), { className: "os-theme-light" });

document.getElementById("interestingThing").addEventListener("click", e => {
    let stuff = document.getElementById("extraStuff");
    if (getComputedStyle(stuff).display === "block")
        stuff.style.display = "none";
    else
        stuff.style.display = "block";
});

I have reproduced some of the styles from my real example in case it's something specific causing the issue. To see the issue, make your browser window tall enough that you can see "LAST THING" without needing a scrollbar. Then click on "Click this thing" to show "Another Tall Thing". A scrollbar should appear so you can scroll down to see "LAST THING". This works in FF as expected, but not in Chrome.

Any help would be appreciated -- so far I'm really liking this scrollbar script.

@KingSora
Copy link
Owner

KingSora commented May 29, 2018

Good day!

As I can clearly see, you are using a flexbox layout here. The default options are set to work flawless with "normal" divs. Please try to set the option sizeAutoCapable to false. I've tested it on this fiddle, and it works fine in Chrome and in Firefox.

Currently I'm working on version 1.5.0 and on a update of the documentation page where I'll write a whole article about flexbox and how the plugin shall be used with it. I'm sorry that it's currently not very clear on how to handle things within a flexbox layout.

In case you are wondering why this behavior is only happening in Chrome and not in Firefox, thats because all browser (and I mean all) are implementing flexbox in a different way. Sometimes you can measure the container size correctly and sometimes not (it also depends on the overflow style of the container).

@yellowsix
Copy link
Author

Thanks for the quick reply -- I should have looked for that setting.

My little test worked out fine with that setting, but my live case did not... must be something else going on that I didn't translate over to the example.

Regardless, now that I know flexbox is a little wacky for doing the measuring required for the scrollbar, I changed it to a css grid instead, and everything works as expected (without having to set sizeAutoCapable to false).

@KingSora
Copy link
Owner

KingSora commented May 30, 2018

I'm sorry to hear that the solution didn't worked out for your live case. Is it possible for you to take a look and figure out what is the difference between your live and this test case? - This would be a great opportunity for me to figure out how to handle more flexbox cases correctly. (and perhaps I can implement something right into the plugin to detect these cases)

I know you've switched to a css grid now, but I have done more investigation and figured the following out:
If you set the style overflow: hidden on the host-element, it also works without sizeAutoCapable in chrome: https://jsfiddle.net/btwfds1y/3/

I've also created a "last-resort" solution which works definitely, it is a bit laborious but it works definitely: https://jsfiddle.net/btwfds1y/2/

@yellowsix
Copy link
Author

Sorry for the slow reply -- I tried it again and it seems to be working now... not sure what I did wrong the first time, but setting sizeAutoCapable to false seems to do the trick, even with flexbox layout.

I ran into another pretty tricky case... I need a virtual list for a very long scrolling list, so I used this simple script that has served me well: https://github.com/sergi/virtual-list

I ran into two problems... and a kind of dirty solution. The first problem is that when I use overlay scrollbars on the container created by this component, then it ends up pointing to the wrong container... I had to create the virtual list, initialize the scrollbars, then dig into the list's code and re-assign its "container" to the content element created by OS. The second problem is that it was listening to a DOM scroll event on the container... but I'm not sure which element it needs to listen to anymore. So I ended up disabling that, and listening to the OS onScroll event, and passing the scrollTop position into a tweaked version of the component's scroll handler.

Not sure if there is a better way to make these play well together... or a different virtual list component that works better with OS...

@KingSora
Copy link
Owner

KingSora commented Jun 9, 2018

The virtual-list indeed offers very little customization possibilities and I figured out it is impossible to use OverlayScrollbars with this plugin. (except if you edit the source code little bit like you mentioned in your post) - Ive created a demo how I would solve the case: https://jsfiddle.net/nyc7d9v3/1/ This "solution" is also very dirty and I can't recommend it.

I've found a plugin which offers a bit more customization possibilities: HyperList
It's very easy to use OverlayScrollbars with this plugin. I've created a demo for you: https://jsfiddle.net/8wko6q0m/
The actual code begins in line 461. HyperList doesn't have a CDN so I had to paste the whole source code into jsfiddle. Please notice the last line where I set style.overflow = "visible". This is very important and could also be done in CSS, but for the sake of this demo I've done it in JS.

To answer your question, the element which is responsible for the actual scrolling is the viewport element. You can get it like this: instance.getElements().viewport. This can also be read here or here in the documentation.

@yellowsix
Copy link
Author

That worked much better -- seems hyperlist is a fork/continuation of the other one I was using, which isn't being updated anymore.

I think all of my more difficult cases are working well now, thanks a lot for the help. The rich API on overlay scrollbars has been very helpful for implementing more complicated components like this one, dropdown lists, etc.

@KingSora KingSora changed the title Scrollbar not sizing in Chrome in some cases Usage with Flexbox and VirtualList Jun 11, 2018
@KingSora
Copy link
Owner

I'm glad everything is working now.
With the release of v1.5.0 the possibilities will be even greater due to the introduction of the extension system.

If you have any other questions or if you find any bugs, please don't hesitate to open a issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants