view-timeline-sticky-offscreen-4.html (3711B)
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 /* top-sticky before entry */ 23 .stickycase4 { 24 background: yellow; 25 position: sticky; 26 top: 600px; 27 height: 200px; 28 } 29 30 #target { 31 position: relative; 32 top: 50px; 33 background: orange; 34 height: 100px; 35 } 36 37 </style> 38 </head> 39 <body> 40 <div id="container"> 41 <div class="space"></div> 42 <div class="space"> 43 <div style="height: 150px"></div> 44 <div id="sticky" class="stickycase4"> 45 <div id="target">Subject</div> 46 </div> 47 </div> 48 <div class="space"></div> 49 </div> 50 <script type="text/javascript"> 51 52 // The "cover" range would be [STATIC_START, STATIC_END] if we ignored 53 // stickiness (i.e., considered only static position). 54 // 55 // STATIC_START = scroll distance to second spacer (50px) 56 // + position of sticky element within its container (150px) 57 // + position of target within sticky element (50px) 58 // STATIC_END = STATIC_START 59 // + viewport height (500px) 60 // + target height (100px) 61 const STATIC_START = 250; 62 const STATIC_END = 850; 63 64 // This is how far the sticky element can move upwards when bottom-stuck. 65 const ROOM_ABOVE = 150; 66 67 // This is how far the sticky element can move downwards when top-stuck. 68 const ROOM_BELOW = 200; 69 70 const TARGET_HEIGHT = 100; 71 const VIEWPORT_HEIGHT = 500; 72 73 promise_test(async t => { 74 await runTimelineRangeTest(t, { 75 rangeStart: { rangeName: 'cover', offset: CSS.percent(0) } , 76 rangeEnd: { rangeName: 'cover', offset: CSS.percent(100) }, 77 startOffset: STATIC_START + ROOM_BELOW, 78 endOffset: STATIC_END + ROOM_BELOW, 79 axis: 'block' 80 }); 81 await runTimelineRangeTest(t, { 82 rangeStart: { rangeName: 'contain', offset: CSS.percent(0) } , 83 rangeEnd: { rangeName: 'contain', offset: CSS.percent(100) }, 84 startOffset: STATIC_START + ROOM_BELOW + TARGET_HEIGHT, 85 endOffset: STATIC_END + ROOM_BELOW - TARGET_HEIGHT, 86 axis: 'block' 87 }); 88 await runTimelineRangeTest(t, { 89 rangeStart: { rangeName: 'entry', offset: CSS.percent(0) }, 90 rangeEnd: { rangeName: 'entry', offset: CSS.percent(100) }, 91 startOffset: STATIC_START + ROOM_BELOW, 92 endOffset: STATIC_START + ROOM_BELOW + TARGET_HEIGHT, 93 axis: 'block' 94 }); 95 await runTimelineRangeTest(t, { 96 rangeStart: { rangeName: 'entry-crossing', offset: CSS.percent(0) }, 97 rangeEnd: { rangeName: 'entry-crossing', offset: CSS.percent(100) }, 98 startOffset: STATIC_START + ROOM_BELOW, 99 endOffset: STATIC_START + ROOM_BELOW + TARGET_HEIGHT, 100 axis: 'block' 101 }); 102 await runTimelineRangeTest(t, { 103 rangeStart: { rangeName: 'exit', offset: CSS.percent(0) }, 104 rangeEnd: { rangeName: 'exit', offset: CSS.percent(100) }, 105 startOffset: STATIC_END + ROOM_BELOW - TARGET_HEIGHT, 106 endOffset: STATIC_END + ROOM_BELOW, 107 axis: 'block' 108 }); 109 await runTimelineRangeTest(t, { 110 rangeStart: { rangeName: 'exit-crossing', offset: CSS.percent(0) }, 111 rangeEnd: { rangeName: 'exit-crossing', offset: CSS.percent(100) }, 112 startOffset: STATIC_END + ROOM_BELOW - TARGET_HEIGHT, 113 endOffset: STATIC_END + ROOM_BELOW, 114 axis: 'block' 115 }); 116 }, 'View timeline top-sticky before entry.'); 117 118 </script> 119 </body> 120 </html>