wpt / css / css-overflow / single-axis-scroll-into-view.html

Status: FAIL | Duration: 44ms | Subtests: 0/1 | Open test on wpt.live | wpt.fyi

/css/css-overflow/single-axis-scroll-into-view.html

<!doctype html>
<meta charset="utf-8">
<title>Single-axis scroll containers with scrollIntoView</title>
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/12289">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<style>
  #outer {
    width: 100px;
    height: 100px;
    overflow-x: clip;
    overflow-y: scroll;
    scrollbar-width: none;
  }
  #inner {
    width: 100px;
    height: 100px;
    overflow-x: scroll;
    overflow-y: clip;
    scrollbar-width: none;
  }
  .inner-spacer {
    height: 220px;
  }
  .spacer {
    height: 100px;
  }
  #target {
    width: 100px;
    height: 60px;
    /* Pushes target to the right while keeping it within inner's clipped block
       axis. The trailing spacer keeps #inner vertically scrollable, so this
       test fails if the clipped axis is scrolled instead of propagating the
       block-axis alignment to #outer. */
    margin-left: 200px;
    margin-top: 20px;
  }
</style>

<div id="outer">
  <!-- Spacer pushes #inner down, creating 300px of scrollable height inside #outer -->
  <div class="spacer"></div>
  <div id="inner">
    <div id="target"></div>
    <div class="inner-spacer"></div>
  </div>
  <div class="spacer"></div>
</div>

<script>
test(() => {
  const outer = document.querySelector('#outer');
  const inner = outer.querySelector('#inner');
  const target = outer.querySelector('#target');

  // Attempt to scroll the target to the top-left of the viewing area
  target.scrollIntoView({block: 'start', inline: 'start', behavior: 'instant'});

  // Check inner container (scrolls X, clips Y)
  // Target is pushed 200px right, so inner should scroll exactly 200px horizontally.
  assert_equals(inner.scrollLeft, 200, 'inner scrolls horizontally to the target');
  assert_equals(inner.scrollTop, 0, 'inner ignores the clipped vertical axis');
  assert_equals(inner.scrollWidth, 300, 'inner scrollWidth retains overflowing content');
  assert_equals(inner.scrollHeight, 300, 'inner scrollHeight retains overflowing content');

  // Check outer container (clips X, scrolls Y)
  // The target sits 20px below the top of #inner, so #outer must scroll the
  // remaining 120px vertically when #inner cannot scroll the clipped axis.
  assert_equals(outer.scrollLeft, 0, 'outer ignores the clipped horizontal axis');
  assert_equals(outer.scrollTop, 120, 'outer scrolls vertically to the target');
  assert_equals(outer.scrollWidth, 100, 'outer scrollWidth naturally fits client width');
  assert_equals(outer.scrollHeight, 300, 'outer scrollHeight retains overflowing content');
}, 'scrollIntoView() respects single-axis limits independently on each ancestor');
</script>