snap-area-capturing-remove-scroll-container.html (3845B)
1 <!DOCTYPE html> 2 <title> 3 When an element no longer captures snap positions (e.g., no longer 4 scrollable), then its currently captured snap areas must be reassigned. 5 </title> 6 <link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#captures-snap-positions"/> 7 <meta name="viewport" content="user-scalable=no"> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 <style> 11 div { 12 position: absolute; 13 margin: 0px; 14 } 15 16 html { 17 scroll-snap-type: y mandatory; 18 } 19 20 body { 21 margin: 0px; 22 } 23 24 #middle-scroller { 25 top: 100px; 26 height: 500px; 27 width: 500px; 28 overflow: scroll; 29 background-color: rgb(12, 61, 2); 30 scroll-snap-type: none; 31 } 32 33 #inner-scroller { 34 top: 200px; 35 height: 400px; 36 width: 400px; 37 overflow: scroll; 38 background-color: rgb(65, 139, 50); 39 scroll-snap-type: y mandatory; 40 } 41 42 .space { 43 width: 2000px; 44 height: 2000px; 45 } 46 47 #inner-snap-area { 48 top: 300px; 49 width: 200px; 50 height: 200px; 51 background-color: blue; 52 scroll-snap-align: start; 53 } 54 55 #document-snap-area { 56 top: 500px; 57 width: 200px; 58 height: 200px; 59 background-color: lightblue; 60 scroll-snap-align: start; 61 } 62 63 </style> 64 <div class="space"></div> 65 <div id="middle-scroller"> 66 <div class="space"></div> 67 <div id="inner-scroller"> 68 <div class="space"></div> 69 <div id="inner-snap-area"></div> 70 </div> 71 </div> 72 </div> 73 <div id="document-snap-area"></div> 74 <script> 75 76 // This tests that making a snap container no longer scrollable will reassign 77 // its snap areas to the next scrollable ancestor, per spec [1]. 78 // [1] https://drafts.csswg.org/css-scroll-snap/#captures-snap-positions 79 test(() => { 80 const inner_scroller = document.getElementById("inner-scroller"); 81 const middle_scroller = document.getElementById("middle-scroller"); 82 const document_scroller = document.scrollingElement; 83 84 // Inner scroller should snap to its captured area. 85 // Middle scroller doesn't snap. 86 // Document scroller should snap to its only captured area. 87 inner_scroller.scrollBy(0,10); 88 middle_scroller.scrollBy(0, 10); 89 // Scroll to (0,600), where we would expect the inner snap area to be relative 90 // to the document scroller. 91 document_scroller.scrollTo(0, 600); 92 assert_equals(inner_scroller.scrollTop, 300); 93 assert_equals(middle_scroller.scrollTop, 10); 94 assert_equals(document_scroller.scrollTop, 500); 95 96 // Inner scroller is no longer a scroll container. 97 inner_scroller.style.setProperty("overflow", "visible"); 98 assert_equals(inner_scroller.scrollTop, 0); 99 assert_equals(middle_scroller.scrollTop, 10); 100 assert_equals(document_scroller.scrollTop, 500); 101 102 // The new snap container is the middle scroller, which has snap-type 'none'. 103 // Per spec, the scroll container should capture snap positions even if it has 104 // snap-type 'none'. 105 // The middle scroller should not snap. 106 // The document scroller should still only snap to its captured snap area. 107 document_scroller.scrollBy(0, 100); 108 middle_scroller.scrollBy(0, 10); 109 assert_equals(inner_scroller.scrollTop, 0); 110 assert_equals(middle_scroller.scrollTop, 20); 111 assert_equals(document_scroller.scrollTop, 500); 112 113 // The scroll container should now be at the document level. 114 middle_scroller.style.setProperty("overflow", "visible"); 115 document_scroller.scrollBy(0, -10); 116 assert_equals(inner_scroller.scrollTop, 0); 117 assert_equals(middle_scroller.scrollTop, 0); 118 119 // Check that the existing snap area did not get removed when reassigning 120 // the inner snap area. 121 assert_equals(document_scroller.scrollTop, 500); 122 123 // Check that the inner snap area got reassigned to the document. 124 document_scroller.scrollBy(0, 150); 125 assert_equals(document_scroller.scrollTop, 600); 126 }, 'Making a snap container not scrollable should promote the next scrollable\ 127 ancestor to become a snap container.'); 128 </script>