[CTW] Bounds incorrect for scrolled position: fixed elements
Categories
(Core :: Disability Access APIs, defect)
Tracking
()
Tracking | Status | |
---|---|---|
firefox111 | --- | fixed |
People
(Reporter: Jamie, Assigned: morgan)
References
(Blocks 1 open bug)
Details
(Whiteboard: [ctw-m5])
Attachments
(1 file)
(deleted),
text/x-phabricator-request
|
Details |
STR:
- Open this test case:
data:text/html,<div style="position: fixed;"><button>top</button></div><script> for (let i = 0; i < 1000; ++i) { const div = document.createElement("div"); div.innerHTML = `<button>${i}</button>`; document.body.append(div); } </script>`
- Get the Accessible for the "top" button.
- Get its bounds.
- Scroll the page to the bottom.
- Get the bounds for the "top" Accessible.
- Expected: Same as step 3.
- Actual: A very negative y coordinate.
Even though the "top" button is a child of a document which has a scroll position, it is position: fixed, so it should not take the scroll position into account.
We probably have a similar problem with position: sticky, but I'm not quite sure how to handle that; it's a bit more complicated.
Reporter | ||
Comment 1•2 years ago
|
||
Yup, I can confirm that we definitely have the same problem for sticky positioning. Test case:
data:text/html,<div style="position: sticky; top: 0px;"><button>top</button></div><script> for (let i = 0; i < 1000; ++i) { const div = document.createElement("div"); div.innerHTML =<button>${i}</button>; document.body.append(div); } </script>
We somehow need to figure out when the element is effectively ignoring the scroll position and when it isn't. We also need to get notified when that changes.
Assignee | ||
Comment 2•2 years ago
|
||
Hmm, looks like we need to respond to things that do scroll suppression
https://drafts.csswg.org/css-scroll-anchoring/#suppression-triggers
Assignee | ||
Updated•2 years ago
|
Assignee | ||
Comment 3•2 years ago
|
||
:Jamie I can't get this test to fail -- I verified that the scroll offset changes for the doc accessible (so the page is scrolling) but it looks like the bounds are correct for the top
button when testing on central. Does this pass for you locally?
accessible/tests/browser/scroll/browser_test_scroll_bounds.js
/**
* Test bounds and scroll offset on fixed-pos accs
*/
addAccessibleTask(
`
<div style="position: fixed;">
<button id="top">top</button>
</div>
`,
async function(browser, docAcc) {
const origBounds = await testBoundsWithContent(docAcc, "top", browser);
await invokeContentTask(browser, [], () => {
for (let i = 0; i < 1000; ++i) {
const div = content.document.createElement("div");
div.innerHTML = "<button>${i}</button>";
content.document.body.append(div);
}
// scroll to the bottom of the page
content.window.scrollTo(0, content.document.body.scrollHeight);
});
await waitForContentPaint(browser);
const newBounds = await testBoundsWithContent(docAcc, "top", browser);
for (let i = 0; i < 4; i++) {
is(
origBounds[i],
newBounds[i],
"Bounds of fixed element are unaffected by scrolling"
);
}
},
{ iframe: true, remoteIframe: true }
);
Assignee | ||
Comment 4•2 years ago
|
||
Reporter | ||
Updated•2 years ago
|
Reporter | ||
Comment 5•2 years ago
|
||
As discussed on Zoom, I think the reason the test doesn't fail is that ParentRelativeBounds adjusts for the scroll position. However, this only works if we happen to push cached bounds for the fixed element after the scroll event (for whatever reason; perhaps reflow). If the scroll event happens after we cache bounds for the fixed element, we often won't push a bounds update.
You could make the test reproduce this problem by moving the script which adds the 1000 buttons into the snippet, rather than doing this in the same task as the scroll. This would be closer to the test case I provided in comment 0.
Assignee | ||
Comment 6•2 years ago
|
||
I thought position:fixed elements were relative to the viewport, but turns out they're relative to their document. So in something like this (sorry for the verbose test case -- you need a scrollable iframe with a fixed element, and that iframe should be embedded in a scrollable top level doc)
data:text/html,<iframe style="margin-left:100px; margin-top:100px;" src="data:text/html,<div style='position:fixed;'>hello world</div>hello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello world"></iframe><br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a
the div in the iframe is fixed, so as you scroll the iframe text it doesn't move. but, if you scroll the top level document the hello world
div inside the iframe scrolls (ie. it isn't fixed in the top level document).
sigh
Updated•2 years ago
|
Updated•2 years ago
|
Comment 8•2 years ago
|
||
bugherder |
Updated•2 years ago
|
Description
•