- From: Emilio Cobos Álvarez via GitHub <sysbot+gh@w3.org>
- Date: Mon, 29 Jul 2019 22:18:42 +0000
- To: public-css-archive@w3.org
aHere's the intersection code that I thought of: https://stackoverflow.com/questions/9011668/get-element-at-point-in-entire-page-even-if-its-not-visible Upon re-reading it I think what that code is trying to do would be better done by something like flex or grid, but I haven't thought out too much how, it seems it's sort of like the masonry layout stuff. Anyhow... The usecase that prompted me to propose it was some investigation in https://github.com/mozilla/fathom/issues/91. But I've seen similar code elsewhere in sites like Facebook and such (see https://bugzilla.mozilla.org/show_bug.cgi?id=1381071#c1 for example). The facebook code is: ```ts function isVisible(element: HTMLElement): boolean { // Look upward in the DOM until we either reach the document or // find something hidden. let elem = element; while ( elem && elem !== document && Style.get(elem, 'visibility') != 'hidden' && Style.get(elem, 'display') != 'none') { elem = elem.parentNode; } // If we reached the document, the element is visible. return elem === document; } ``` The code in the Mozilla add-on was similar too: ```js export function isVisible(fnodeOrElement) { const element = toDomElement(fnodeOrElement); for (const ancestor of ancestors(element)) { const style = getComputedStyle(ancestor); if (style.visibility === 'hidden' || style.display === 'none' || style.opacity === '0' || style.width === '0' || style.height === '0') { return false; } } return true; } ``` (I skipped [some branch](https://github.com/mozilla/fathom/blob/5cf2e902d3cdd01368ed72e7796b848f741e17b0/utilsForFrontend.mjs#L477) which was doing some viewport stuff because it's not clear what it's trying to do, I think it's trying to check elements scrolled out of view towards the top, or something). The question that code is trying to answer is whether a given node is "visible", for some definition of visible. Both functions are bogus in multiple ways: * They don't work with anything that looks like shadow DOM in any way. * They assume `visibility` works differently than how it works (`visibility: visible` inside `visibility: hidden` is definitely visible). * The `style.width` and `style.height` checks in the add-on code is wrong (should be `0px` instead), they're meaningless is `overflow` is `visible`, etc... * They don't handle other ways to make an element "hidden". The add-on use-case is even worse because walking the DOM from an add-on is slower due to security wrappers / proxies. In the add-on use-case at least, the complaint against `elementsFromPoint()` was that it returned false for out-of-viewport elements. But using it actually _improved_ performance compared to all the DOM walking and layout querying (mostly because of the reduced number of DOM calls, actually). It seems to me like a good improvement over those two functions but, that being said, chances are that a more thought-out proposal may want a bit more flexibility. For example, people may want to ignore all scroller clips, or maybe only those with user-scrollable overflow (that is, don't ignore `overflow: hidden` clips but ignore `overflow: scroll` clips)... In any case ignoring the viewport clip is a pretty good improvement over the situation now. The Facebook code doesn't need to deal with all of the web, but libraries / frameworks and extensions do, this could allow them to write actually correct code :) -- GitHub Notification of comment by emilio Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/4122#issuecomment-516183855 using your GitHub account
Received on Monday, 29 July 2019 22:18:44 UTC