quasar
quasar copied to clipboard
QMenu remains visible for scrolled out elements
What happened?
A QMenu linked to an element within a scroll area continues to stay visible even when the element is scrolled out of view, thereby obscuring other elements:
What did you expect to happen?
The menu should either remain confined within the scroll area or become hidden upon scrolling. Adjusting the z-index does not appear to rectify the issue.
Reproduction URL
https://codepen.io/eliaspanagiotidis/pen/RwvjqYZ?editors=1010
How to reproduce?
Press the "Open menu" button to open the menu. Scroll up using the mouse (not the scrollbar).
Flavour
Quasar CLI with Vite (@quasar/cli | @quasar/app-vite)
Areas
Components (quasar)
Platforms/Browsers
No response
Quasar info output
No response
Relevant log output
No response
Additional context
No response
The easiest solution that crosses my mind is to set the absolute position on the menu, this way it is going to stay attached to the element that triggered it. Another thing I assume might work is to use Intersection API which would allow to track if menu or the element that prompted it is no longer in a viewport and then close it.
Thank you, @thevladisss. I’ve tried using absolute positioning, but it doesn’t seem to make a difference. The Intersection API could be a potential solution, but it has its drawbacks. Firstly, it might be excessive if multiple elements on a page are linked with QMenus. Secondly, it doesn’t completely solve the problem, especially when the element is near the top boundary of its container or partially hidden.
Currently, my workaround involves the following steps: When a QMenu is displayed (a) the "scrollTop" of the target element's first scrollable parent is stored and (b) a scroll event listener is added to the element (the event is removed when the QMenu is hidden). When a scroll event occurs, the current location is compared with the initial one. If the distance exceeds a certain threshold, the QMenu is hidden.
This method seems to work well, I’m wondering if there’s a simpler way to implement something similar directly in the QMenu.
Thank you, @thevladisss. I’ve tried using absolute positioning, but it doesn’t seem to make a difference. The Intersection API could be a potential solution, but it has its drawbacks. Firstly, it might be excessive if multiple elements on a page are linked with QMenus. Secondly, it doesn’t completely solve the problem, especially when the element is near the top boundary of its container or partially hidden.
Currently, my workaround involves the following steps: When a QMenu is displayed (a) the "scrollTop" of the target element's first scrollable parent is stored and (b) a scroll event listener is added to the element (the event is removed when the QMenu is hidden). When a scroll event occurs, the current location is compared with the initial one. If the distance exceeds a certain threshold, the QMenu is hidden.
This method seems to work well, I’m wondering if there’s a simpler way to implement something similar directly in the QMenu.
Hi @eliaspanagiotidis. I've been thinking on your answer, and another suggestion I can have is to force the menu to position absolute which and use Intrsection API on the very menu, or to be more precise on its content. This would mean that if you open the menu and it is no longer in your viewport as it is absolute to its anchor element, it would would close self (in my example I d oits via ref and QMenu API).
This eliminates the problem with intersection API mentioned by you, as now it is not set onto the element that triggered the menu as there might be many.
@thevladisss it seems you can't work on the QMenu content without hacks as it is handled internally by Quasar as a direct child of <body>.
From the manual:
Don’t worry about QMenu content inheriting CSS from the container as the QMenu will be injected as a direct child of <body> through a Quasar Portal.