nested-scrollIntoView-snaps.html (3377B)
1 <!DOCTYPE html> 2 <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-type" /> 3 <meta name="viewport" content="user-scalable=no"> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <style> 7 div { 8 position: absolute; 9 } 10 :root { 11 overflow: scroll; 12 scroll-snap-type: both mandatory; 13 } 14 .scroller { 15 overflow: scroll; 16 scroll-snap-type: both mandatory; 17 padding: 0px; 18 } 19 #outer { 20 left: 1000px; 21 top: 1000px; 22 width: 600px; 23 height: 600px; 24 } 25 #out-snap-1 { 26 scroll-snap-align: start; 27 left: 1200px; 28 top: 1200px; 29 width: 10px; 30 height: 10px; 31 } 32 #out-snap-2 { 33 scroll-snap-align: start; 34 left: 1100px; 35 top: 1100px; 36 width: 10px; 37 height: 10px; 38 } 39 #inner { 40 left: 1000px; 41 top: 1000px; 42 width: 400px; 43 height: 400px; 44 } 45 .space { 46 left: 0px; 47 top: 0px; 48 width: 3000px; 49 height: 3000px; 50 } 51 #target { 52 scroll-snap-align: end; 53 left: 800px; 54 top: 800px; 55 width: 200px; 56 height: 200px; 57 } 58 </style> 59 60 <div class="space"></div> 61 <div id="out-snap-1"></div> 62 <div id="out-snap-2"></div> 63 <div class="scroller" id="outer"> 64 <div class="space"></div> 65 <div class="scroller" id="inner"> 66 <div class="space"></div> 67 <div id="target"></div> 68 </div> 69 </div> 70 71 <script> 72 var outer = document.getElementById("outer"); 73 var inner = document.getElementById("inner"); 74 var target = document.getElementById("target"); 75 76 test(() => { 77 // Initial layout triggers a scroll snap. Reset position before calling 78 // scrollIntoView. 79 window.scrollTo(0, 0); 80 outer.scrollTo(0, 0); 81 inner.scrollTo(0, 0); 82 83 target.scrollIntoView({inline: "start", block: "start"}); 84 // Although the scrollIntoView specified "start" as the alignment, the target 85 // has "end" as its snap-alignment. So the inner scroller finishes with "end" 86 // alignment 87 assert_equals(inner.scrollLeft, 1000 - inner.clientWidth, "ScrollIntoView lands on the target's snap position regardless of the specified alignment."); 88 assert_equals(inner.scrollTop, 1000 - inner.clientHeight, "ScrollIntoView lands on the target's snap position regardless of the specified alignment."); 89 90 // Since there is no snap points defined in the outer scroller, the outer 91 // scroller finishes with "start" alignment, as specified in scrollIntoView. 92 // Note that the "start" alignment aligns the target's top-left corner 93 //(inner.left + inner.clientWidth - target.width, inner.top + inner.clientHeight - target.height) 94 // with the outer scroller's top-left corner. 95 assert_equals(outer.scrollLeft, 800 + inner.clientWidth, "ScrollIntoView ends with the specified alignment if no snap position is specified."); 96 assert_equals(outer.scrollTop, 800 + inner.clientHeight, "ScrollIntoView ends with the specified alignment if no snap position is specified."); 97 98 // Although the scrollIntoView specified "start" as the alignment, the window 99 // has two other elements with snap points. So the window finishes with the 100 // closest snap point. 101 assert_equals(window.scrollX, 1100, "ScrollIntoView lands on the snap position closest to the specified alignment."); 102 assert_equals(window.scrollY, 1100, "ScrollIntoView lands on the snap position closest to the specified alignment."); 103 }, "All the scrollers affected by scrollIntoView should land on a snap position if one exists. Otherwise, land according to the specified alignment"); 104 </script>