Status: FAIL | Duration: 46ms | Subtests: 0/4 | Open test on wpt.live | wpt.fyi
Data from commit:
1884860 Copy-on-write style attribute blocks that are in the rule tree (#831) (2026-09-02)
| Subtest | Status | Message |
|---|---|---|
| [Box A] scrollIntoView from unscrollable position:fixed | FAIL | frames is not defined |
| [Box B] scrollIntoView from unscrollable position:fixed in iframe | FAIL | frames is not defined |
| [Box C] scrollIntoView from scrollable position:fixed | FAIL | frames is not defined |
| [Box D] scrollIntoView from scrollable position:fixed in iframe | FAIL | frames is not defined |
/css/cssom-view/scrollIntoView-fixed.html
<!DOCTYPE html> <html> <head> <title>CSSOM View - scrollIntoView from position:fixed</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,minimum-scale=1"> <link rel="author" title="David Bokan" href="mailto:bokan@chromium.org"> <link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <style> body { width: 1000vw; height: 1000vh; /* stripes so we can see scroll offset more easily */ background: repeating-linear-gradient( 45deg, #A2CFD9, #A2CFD9 100px, #C3F3FF 100px, #C3F3FF 200px ); } .fixedContainer { position: fixed; bottom: 10px; left: 10px; width: 150px; height: 150px; background-color: coral; } .fixedContainer.scrollable { overflow: auto; left: unset; right: 10px; } button { position: absolute; margin: 5px; } .target { position: absolute; width: 10px; height: 10px; background-color: blue; left: 50%; top: 50%; } .scrollable .target { left: 200%; top: 200%; } iframe { width: 96vw; height: 300px; position: absolute; left: 2vw; top: 100px; } </style> <script> </script> </head> <body> <div style="width:90vw"> <p> The orange boxes are position: fixed. Clicking ScrollIntoView in each box will attempt to scroll into view the blue target element inside that fixed container to block/inline: start (i.e. aligned with top left corner in RTL). </p> <p> scrollIntoView from a position:fixed element must not scroll its containing frame; however, it must scroll further ancestor scrollers as the element isn't fixed in relation to them. </p> </div> <iframe></iframe> <div class="fixedContainer"> Box A <button id="fixedContainerBtn">ScrollIntoView</button> <div class="target"></div> </div> <div class="fixedContainer scrollable"> Box C <button id="scrollableFixedContainerBtn">ScrollIntoView</button> <div class="target"></div> </div> <script> if (typeof setup != 'undefined') { setup({ explicit_done: true }); window.addEventListener("load", runTests); } function scrollIntoView(evt) { const container = evt.target.closest('.fixedContainer'); const target = container.querySelector('.target'); target.scrollIntoView({block: 'start', inline: 'start'}); } document.querySelectorAll('button').forEach((btn) => { btn.addEventListener('click', scrollIntoView); }); const iframe = document.querySelector('iframe'); iframe.onload = () => { frames[0].document.querySelectorAll('button').forEach((btn) => { btn.addEventListener('click', scrollIntoView); }); } iframe.srcdoc = ` <!DOCTYPE html> <style> body { height: 200vh; width: 200vw; /* stripes so we can see scroll offset more easily */ background: repeating-linear-gradient( 45deg, #C3A2D9, #C3A2D9 50px, #E5C0FF 50px, #E5C0FF 100px ); } .fixedContainer { position: fixed; bottom: 10px; left: 10px; width: 150px; height: 150px; background-color: coral; } .fixedContainer.scrollable { overflow: auto; left: unset; right: 10px; } button { position: absolute; margin: 5px; } .target { position: absolute; width: 10px; height: 10px; background-color: blue; left: 50%; top: 50%; } .scrollable .target { left: 200%; top: 200%; } </style> IFRAME <div class="fixedContainer"> Box B <button id="fixedContainerBtn">ScrollIntoView</button> <div class="target"></div> </div> <div class="fixedContainer scrollable"> Box D <button id="scrollableFixedContainerBtn">ScrollIntoView</button> <div class="target"></div> </div> `; function reset() { [document, frames[0].document].forEach((doc) => { doc.scrollingElement.scrollLeft = 0; doc.scrollingElement.scrollTop = 0; doc.querySelectorAll('.fixedContainer').forEach((e) => { e.scrollLeft = 0; e.scrollTop = 0; }); }); } function runTests() { // Test scrollIntoView from a plain, unscrollable position:fixed element. // Nothing should scroll. test(() => { reset() const container = document.querySelector('.fixedContainer:not(.scrollable)'); const target = container.querySelector('.target'); target.scrollIntoView({block: 'start', inline: 'start'}); assert_equals(window.scrollX, 0, 'must not scroll window [scrollX]'); assert_equals(window.scrollY, 0, 'must not scroll window [scrollY]'); }, `[Box A] scrollIntoView from unscrollable position:fixed`); // Same as above but from inside an iframe. Since the container is fixed // only to the iframe, we should scroll the outer window. test(() => { reset() const container = frames[0].document.querySelector('.fixedContainer:not(.scrollable)'); const target = container.querySelector('.target'); target.scrollIntoView({block: 'start', inline: 'start'}); // Large approx to account for differences like scrollbars assert_approx_equals(window.scrollX, 100, 20, 'must scroll outer window [scrollX]'); assert_approx_equals(window.scrollY, 300, 20, 'must scroll outer window [scrollY]'); assert_equals(frames[0].window.scrollX, 0, 'must not scroll iframe [scrollX]'); assert_equals(frames[0].window.scrollY, 0, 'must not scroll iframe [scrollY]'); }, `[Box B] scrollIntoView from unscrollable position:fixed in iframe`); // Test scrollIntoView from a scroller that's position fixed. The // scroller should be scrolled but shouldn't bubble the scroll as the // window scrolling won't change the target's position. test(() => { reset() const container = document.querySelector('.fixedContainer.scrollable'); const target = container.querySelector('.target'); target.scrollIntoView({block: 'start', inline: 'start'}); // Large approx to account for differences like scrollbars assert_equals(window.scrollX, 0, 'must not scroll window [scrollX]'); assert_equals(window.scrollY, 0, 'must not scroll window [scrollY]'); assert_approx_equals(container.scrollLeft, 145, 20, 'scrollIntoView in container [scrollLeft]'); assert_approx_equals(container.scrollTop, 145, 20, 'scrollIntoView in container [scrollTop]'); }, `[Box C] scrollIntoView from scrollable position:fixed`); // Same as above but from inside an iframe. In this case, the scroller // should bubble the scroll but skip its own frame (as it's fixed with // respect to its own frame's scroll offset) and bubble to the outer // window. test(() => { reset() const container = frames[0].document.querySelector('.fixedContainer.scrollable'); const target = container.querySelector('.target'); target.scrollIntoView({block: 'start', inline: 'start'}); // Large approx to account for differences like scrollbars assert_approx_equals(window.scrollX, 740, 20, 'must scroll outer window [scrollX]'); assert_approx_equals(window.scrollY, 360, 20, 'must scroll outer window [scrollY]'); assert_approx_equals(container.scrollLeft, 145, 20, 'scrollIntoView in container [scrollLeft]'); assert_approx_equals(container.scrollTop, 145, 20, 'scrollIntoView in container [scrollTop]'); assert_equals(frames[0].window.scrollX, 0, 'must not scroll iframe [scrollX]'); assert_equals(frames[0].window.scrollY, 0, 'must not scroll iframe [scrollY]'); }, `[Box D] scrollIntoView from scrollable position:fixed in iframe`); done(); } </script> </body> </html>