| <!DOCTYPE html> |
| <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-type" /> |
| <meta name="viewport" content="user-scalable=no"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <style> |
| div { |
| position: absolute; |
| } |
| :root { |
| overflow: scroll; |
| scroll-snap-type: both mandatory; |
| } |
| .scroller { |
| overflow: scroll; |
| scroll-snap-type: both mandatory; |
| padding: 0px; |
| } |
| #outer { |
| left: 1000px; |
| top: 1000px; |
| width: 600px; |
| height: 600px; |
| } |
| #out-snap-1 { |
| scroll-snap-align: start; |
| left: 1200px; |
| top: 1200px; |
| width: 10px; |
| height: 10px; |
| } |
| #out-snap-2 { |
| scroll-snap-align: start; |
| left: 1100px; |
| top: 1100px; |
| width: 10px; |
| height: 10px; |
| } |
| #inner { |
| left: 1000px; |
| top: 1000px; |
| width: 400px; |
| height: 400px; |
| } |
| .space { |
| left: 0px; |
| top: 0px; |
| width: 3000px; |
| height: 3000px; |
| } |
| #target { |
| scroll-snap-align: end; |
| left: 800px; |
| top: 800px; |
| width: 200px; |
| height: 200px; |
| } |
| </style> |
| |
| <div class="space"></div> |
| <div id="out-snap-1"></div> |
| <div id="out-snap-2"></div> |
| <div class="scroller" id="outer"> |
| <div class="space"></div> |
| <div class="scroller" id="inner"> |
| <div class="space"></div> |
| <div id="target"></div> |
| </div> |
| </div> |
| |
| <script> |
| var outer = document.getElementById("outer"); |
| var inner = document.getElementById("inner"); |
| var target = document.getElementById("target"); |
| |
| test(() => { |
| assert_equals(window.scrollX, 0); |
| assert_equals(window.scrollY, 0); |
| assert_equals(outer.scrollLeft, 0); |
| assert_equals(outer.scrollTop, 0); |
| assert_equals(inner.scrollLeft, 0); |
| assert_equals(inner.scrollTop, 0); |
| |
| target.scrollIntoView({inline: "start", block: "start"}); |
| // Although the scrollIntoView specified "start" as the alignment, the target |
| // has "end" as its snap-alignment. So the inner scroller finishes with "end" |
| // alignment |
| assert_equals(inner.scrollLeft, 1000 - inner.clientWidth, "ScrollIntoView lands on the target's snap position regardless of the specified alignment."); |
| assert_equals(inner.scrollTop, 1000 - inner.clientHeight, "ScrollIntoView lands on the target's snap position regardless of the specified alignment."); |
| |
| // Since there is no snap points defined in the outer scroller, the outer |
| // scroller finishes with "start" alignment, as specified in scrollIntoView. |
| // Note that the "start" alignment aligns the target's top-left corner |
| //(inner.left + inner.clientWidth - target.width, inner.top + inner.clientHeight - target.height) |
| // with the outer scroller's top-left corner. |
| assert_equals(outer.scrollLeft, 800 + inner.clientWidth, "ScrollIntoView ends with the specified alignment if no snap position is specified."); |
| assert_equals(outer.scrollTop, 800 + inner.clientHeight, "ScrollIntoView ends with the specified alignment if no snap position is specified."); |
| |
| // Although the scrollIntoView specified "start" as the alignment, the window |
| // has two other elements with snap points. So the window finishes with the |
| // closest snap point. |
| assert_equals(window.scrollX, 1100, "ScrollIntoView lands on the snap position closest to the specified alignment."); |
| assert_equals(window.scrollY, 1100, "ScrollIntoView lands on the snap position closest to the specified alignment."); |
| }, "All the scrollers affected by scrollIntoView should land on a snap position if one exists. Otherwise, land according to the specified alignment"); |
| </script> |