view-timeline-sticky-offscreen-6.html (3926B)
1 <!DOCTYPE html> 2 <html id="top"> 3 <head> 4 <meta charset="utf-8"> 5 <title>View timeline with sticky during entry/exit</title> 6 <link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#viewtimeline-interface"> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <script src="/web-animations/testcommon.js"></script> 10 <script src="/scroll-animations/scroll-timelines/testcommon.js"></script> 11 <script src="/scroll-animations/view-timelines/testcommon.js"></script> 12 <style> 13 14 #container { 15 height: 500px; 16 overflow: auto; 17 } 18 .space { 19 height: 550px; 20 } 21 22 /* target > viewport, bottom-sticky during entry and top-sticky during exit */ 23 .stickycase6 { 24 background: yellow; 25 position: sticky; 26 top: -200px; 27 bottom: -200px; 28 height: 700px; 29 } 30 31 #target { 32 position: relative; 33 top: 50px; 34 background: orange; 35 height: 600px; 36 } 37 38 .space:has(.stickycase6), 39 .space:has(.stickycase7) { 40 height: 1050px; 41 } 42 43 </style> 44 </head> 45 <body> 46 <div id="container"> 47 <div class="space"></div> 48 <div class="space"> 49 <div style="height: 150px"></div> 50 <div id="sticky" class="stickycase6"> 51 <div id="target">Subject</div> 52 </div> 53 </div> 54 <div class="space"></div> 55 </div> 56 <script type="text/javascript"> 57 58 // The "cover" range would be [STATIC_START, STATIC_END] if we ignored 59 // stickiness (i.e., considered only static position). 60 // 61 // STATIC_START = scroll distance to second spacer (50px) 62 // + position of sticky element within its container (150px) 63 // + position of target within sticky element (50px) 64 // STATIC_END = STATIC_START 65 // + viewport height (500px) 66 // + target height (100px) 67 const STATIC_START = 250; 68 const BIG_TARGET_STATIC_END = 1350; 69 70 // This is how far the sticky element can move upwards when bottom-stuck. 71 const ROOM_ABOVE = 150; 72 73 // This is how far the sticky element can move downwards when top-stuck. 74 const ROOM_BELOW = 200; 75 76 const BIG_TARGET_HEIGHT = 600; 77 const VIEWPORT_HEIGHT = 500; 78 79 promise_test(async t => { 80 await runTimelineRangeTest(t, { 81 rangeStart: { rangeName: 'cover', offset: CSS.percent(0) } , 82 rangeEnd: { rangeName: 'cover', offset: CSS.percent(100) }, 83 startOffset: STATIC_START - ROOM_ABOVE, 84 endOffset: BIG_TARGET_STATIC_END + ROOM_BELOW, 85 axis: 'block' 86 }); 87 await runTimelineRangeTest(t, { 88 rangeStart: { rangeName: 'contain', offset: CSS.percent(0) } , 89 rangeEnd: { rangeName: 'contain', offset: CSS.percent(100) }, 90 startOffset: STATIC_START + VIEWPORT_HEIGHT, 91 endOffset: BIG_TARGET_STATIC_END - VIEWPORT_HEIGHT, 92 axis: 'block' 93 }); 94 await runTimelineRangeTest(t, { 95 rangeStart: { rangeName: 'entry', offset: CSS.percent(0) }, 96 rangeEnd: { rangeName: 'entry', offset: CSS.percent(100) }, 97 startOffset: STATIC_START - ROOM_ABOVE, 98 endOffset: STATIC_START + VIEWPORT_HEIGHT, 99 axis: 'block' 100 }); 101 await runTimelineRangeTest(t, { 102 rangeStart: { rangeName: 'entry-crossing', offset: CSS.percent(0) }, 103 rangeEnd: { rangeName: 'entry-crossing', offset: CSS.percent(100) }, 104 startOffset: STATIC_START - ROOM_ABOVE, 105 endOffset: BIG_TARGET_STATIC_END - VIEWPORT_HEIGHT, 106 axis: 'block' 107 }); 108 await runTimelineRangeTest(t, { 109 rangeStart: { rangeName: 'exit', offset: CSS.percent(0) }, 110 rangeEnd: { rangeName: 'exit', offset: CSS.percent(100) }, 111 startOffset: BIG_TARGET_STATIC_END - VIEWPORT_HEIGHT, 112 endOffset: BIG_TARGET_STATIC_END + ROOM_BELOW, 113 axis: 'block' 114 }); 115 await runTimelineRangeTest(t, { 116 rangeStart: { rangeName: 'exit-crossing', offset: CSS.percent(0) }, 117 rangeEnd: { rangeName: 'exit-crossing', offset: CSS.percent(100) }, 118 startOffset: STATIC_START + VIEWPORT_HEIGHT, 119 endOffset: BIG_TARGET_STATIC_END + ROOM_BELOW, 120 axis: 'block' 121 }); 122 }, 'View timeline target > viewport, ' + 123 'bottom-sticky during entry and top-sticky during exit.'); 124 125 </script> 126 </body> 127 </html>