position-sticky-nested-top.html (3284B)
1 <!DOCTYPE html> 2 <title>Nested top-constrainted position:sticky elements should render correctly</title> 3 <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> 4 <meta name="assert" content="This test checks that nested position:sticky elements with a top constraint render correctly" /> 5 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 9 <script src="../resources/sticky-util.js"></script> 10 11 <body></body> 12 13 <script> 14 test(() => { 15 const elements = setupNestedStickyTest('top', 50, 60); 16 elements.scroller.scrollTop = 100; 17 const nonStickyTopY = elements.container.offsetTop + 18 elements.filler.clientHeight; 19 assert_equals(elements.sticky.offsetTop, nonStickyTopY); 20 // The inner sticky should not be offset from the outer. 21 assert_equals(elements.innerSticky.offsetTop, 0); 22 }, 'before reaching the sticking point, neither sticky box should be offset'); 23 24 test(() => { 25 const elements = setupNestedStickyTest('top', 50, 60); 26 elements.scroller.scrollTop = 145; 27 const nonStickyTopY = elements.container.offsetTop + 28 elements.filler.clientHeight; 29 assert_equals(elements.sticky.offsetTop, nonStickyTopY); 30 assert_equals(elements.innerSticky.offsetTop, 5); 31 }, 'the inner sticky can stick before the outer one if necessary'); 32 33 test(() => { 34 const elements = setupNestedStickyTest('top', 50, 60); 35 elements.scroller.scrollTop = 200; 36 37 // This math cancels to sticky.offsetTop == (scroller.scrollTop + 50), but 38 // for clarity the calculations are left explicit. 39 const nonStickyTopY = elements.container.offsetTop + 40 elements.filler.clientHeight; 41 const targetTopY = elements.scroller.scrollTop + 50; 42 const stickyOffset = targetTopY - nonStickyTopY; 43 assert_equals(elements.sticky.offsetTop, nonStickyTopY + stickyOffset); 44 45 // The inner sticky has similar math, but its offsetTop is relative to the 46 // sticky element and in this test is the difference between the top values. 47 assert_equals(elements.innerSticky.offsetTop, 10); 48 }, 'both sticky boxes can be stuck at the same time'); 49 50 test(() => { 51 const elements = setupNestedStickyTest('top', 50, 60); 52 elements.scroller.scrollTop = 300; 53 const maxOffsetInContainer = elements.container.offsetTop + 54 elements.container.clientHeight - elements.sticky.clientHeight; 55 assert_equals(elements.sticky.offsetTop, maxOffsetInContainer); 56 const maxOffsetInOuterSticky = elements.sticky.clientHeight - 57 elements.innerSticky.clientHeight; 58 assert_equals(elements.innerSticky.offsetTop, maxOffsetInOuterSticky); 59 }, 'neither sticky can escape their containing block'); 60 61 test(() => { 62 const elements = setupNestedStickyTest('top', 50, 300); 63 elements.scroller.scrollTop = 100; 64 // The outer sticky has not stuck yet. 65 const nonStickyTopY = elements.container.offsetTop + 66 elements.filler.clientHeight; 67 assert_equals(elements.sticky.offsetTop, nonStickyTopY); 68 // But the inner sticky still cannot escape the outer sticky (as it is the 69 // containing block). 70 const maxOffsetInOuterSticky = elements.sticky.clientHeight - 71 elements.innerSticky.clientHeight; 72 assert_equals(elements.innerSticky.offsetTop, maxOffsetInOuterSticky); 73 }, 'the inner sticky cannot be pushed outside the outer sticky'); 74 </script>