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