-
Notifications
You must be signed in to change notification settings - Fork 642
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
Add API for getting the visible bounding rect an element can be placed inside #6132
Comments
Your algorithm kinda looks like https://www.w3.org/TR/intersection-observer/#calculate-intersection-rect-algo |
I think you're right, it looks a lot like Step 3 of that algo:
Perhaps this algo can be abstracted out into a method on the HTMLElement definition? |
I don't think the intersection rectangle is exactly what is needed to solve this problem. Furthermore, browsers are not consistent on how it is calculated. I couldn't find any implementation that calculates the intersection rectangle in a way that lets me discover the clipping rectangle. Here is a CodePen that demonstrates one inconsistency. We have a scrollable container (the intersection root) that is 500px tall, with some top padding, a 100px tall element (pink) followed by a 2000px tall element (blue) that is the intersection target. As the container scrolls, we log out the height of the intersection rect. Clearly, when scrolled far enough, we should log 500, since the blue is filling the 500px-tall container, but instead, we log at most 400. The 100px of padding seems to get lost. Chrome and Safari behave the same (modulo decimal precision). Up until recently, so did Firefox, but the latest Firefox works as expected. However, for another issue, change To @keithamus's point, |
Originally from whatwg/dom#964
I guess this is related to multiple parts of the spec, css-overflow-4, css-position-3
When designing a system for popovers, we came across a rather tricky area of the DOM: getting a computed rectangle of the range of visible pixels an element could be placed in, such that the top-left pixel is visible. I think the specs refer to this concept as a
scrollport
.To achieve this is difficult because most DOM APIs to get these dimensions are either speculative, in that they will provide a "suggested" value, e.g.
.style.height
, or actualized, for examplegetBoundingClientRect()
(which gets real pixels on the screen but doesn't account for overflow). The answer to the question "where can an element render and still be visible in the viewport" is somewhere in between, as it includes accidental complexity the CSS box model (borders are clipping, overflow only impacts positioned elements), API idiosyncrasies (document
is not an element and so has nogetBoundingClientRect()
,document.body
nordocument.body.parentElement
areoverflow: visible
by default, despite the window having a scrollbar).The answer comes after much edge-case testing, the behaviour is something like:
overflow: scroll
, and notposition: static
.window
is, so enact specific behavior here.This will get an absolute clipping rect, which gives the dimensions that an element is able to render into. It does not account for any positioned elements and how that may affect positioning.
There exists a ton of code in the wild for popups and their variants (toasts, tooltips, menus, dialogs) and all require this kind of code. Some fall back for detecting if the container sits outside the windows dimensions but this can cause all kinds of overflow bugs as soon as they're nested inside an overflow container.
This feels like something the browser would keep track of during a rendering path? Is it possible to expose this kind of "clipping rect" via a DOM API?
The text was updated successfully, but these errors were encountered: