diff options
Diffstat (limited to 'testing/web-platform/tests/css/css-position/sticky')
119 files changed, 8028 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-bottom-002.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-bottom-002.html new file mode 100644 index 0000000000..980de2e651 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-bottom-002.html @@ -0,0 +1,121 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Position Test: sticky element with bottom offset specified with px unit</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + <link rel="match" href="reference/position-sticky-bottom-002-ref.html"> + + <meta name="flags" content=""> + + <style> + div.scrolling-container + { + background-image: url("support/100x100-red.png"); + background-repeat: no-repeat; + display: inline-block; + height: 250px; + margin-right: 30px; + overflow: auto; + position: static; + width: 150px; + } + + div#first-scrolling-container + { + background-position: left 75px; + } + + div#second-scrolling-container + { + background-position: left 50px; + } + + div#third-scrolling-container + { + background-position: left top; + } + + div.vertical-spacer + { + height: 100px; + } + + div.sticky + { + background-color: green; + bottom: 100px; + height: 100px; + position: sticky; + width: 100px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollTop = 25; document.getElementById("second-scrolling-container").scrollTop = 100; document.getElementById("third-scrolling-container").scrollTop = 200;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <!-- + first-scrolling-container: before reaching the sticking point + --> + + <div id="first-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="first-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <!-- + second-scrolling-container: when reaching the sticking point and beyond + --> + + <div id="second-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="second-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + + <div id="third-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="third-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-bottom-003.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-bottom-003.html new file mode 100644 index 0000000000..649dfc9d36 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-bottom-003.html @@ -0,0 +1,121 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Position Test: sticky element with bottom offset specified with percentage unit</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + <link rel="match" href="reference/position-sticky-bottom-002-ref.html"> + + <meta name="flags" content=""> + + <style> + div.scrolling-container + { + background-image: url("support/100x100-red.png"); + background-repeat: no-repeat; + display: inline-block; + height: 250px; + margin-right: 30px; + overflow: auto; + position: static; + width: 150px; + } + + div#first-scrolling-container + { + background-position: left 75px; + } + + div#second-scrolling-container + { + background-position: left 50px; + } + + div#third-scrolling-container + { + background-position: left top; + } + + div.vertical-spacer + { + height: 100px; + } + + div.sticky + { + background-color: green; + bottom: 40%; + height: 100px; + position: sticky; + width: 100px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollTop = 25; document.getElementById("second-scrolling-container").scrollTop = 100; document.getElementById("third-scrolling-container").scrollTop = 200;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <!-- + first-scrolling-container: before reaching the sticking point + --> + + <div id="first-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="first-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <!-- + second-scrolling-container: when reaching the sticking point and beyond + --> + + <div id="second-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="second-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + + <div id="third-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="third-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-bottom.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-bottom.html new file mode 100644 index 0000000000..9cfae6d3ba --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-bottom.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<title>position:sticky elements should respect the bottom constraint</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements obey their bottom anchor after scrolling" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body></body> + +<script> +test(() => { + const elements = setupStickyTest('bottom', 25); + elements.scroller.scrollTop = 300; + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + assert_equals(elements.sticky.offsetTop, nonStickyTopY); +}, 'before reaching the sticking point the sticky box should not be offset'); + +test(() => { + const elements = setupStickyTest('bottom', 25); + elements.scroller.scrollTop = 100; + + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + const nonStickyBottomY = nonStickyTopY + elements.sticky.clientHeight; + const targetBottomY = elements.scroller.clientHeight + + elements.scroller.scrollTop - 25; + const stickyOffset = nonStickyBottomY - targetBottomY; + + assert_equals(elements.sticky.offsetTop, nonStickyTopY - stickyOffset); +}, 'after reaching the sticking point the sticky box should be offset'); + +test(() => { + const elements = setupStickyTest('bottom', 25); + elements.scroller.scrollTop = 0; + assert_equals(elements.sticky.offsetTop, elements.container.offsetTop); +}, 'the sticky box should not be pushed outside its containing block'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-change-top-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-change-top-ref.html new file mode 100644 index 0000000000..8ccc1548ef --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-change-top-ref.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title>Reference for sticky elements should invalidate when top/left/bottom/right changes</title> + +<style> +.box { + /* Triggers promotion without creating stacking context. */ + backface-visibility: hidden; + background: green; + position: sticky; + top: 200px; + width: 100px; + height: 100px; +} + +.spacer { + height: 200vh; +} +</style> + +<div class="box"></div> +<div class="spacer"></div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-change-top.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-change-top.html new file mode 100644 index 0000000000..6a327ccd56 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-change-top.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html class='reftest-wait'> +<title>Sticky elements should invalidate when top/left/bottom/right changes</title> +<link rel="match" href="position-sticky-change-top-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<link rel="help" href="https://crbug.com/939632"> +<meta name="assert" content="This test checks that sticky elements are invalidated correctly when top/left/bottom/right change "/> + +<script src="/common/reftest-wait.js"></script> +<script src="../resources/ref-rectangle.js"></script> + +<!-- + It is important for this test that the sticky element is viewport-bound, and + that multiple animation frames pass before changing the style. +--> +<style> +.marker { + background: red; + position: absolute; + top: 200px; + height: 100px; + width: 100px; +} + +.sticky { + /* Triggers promotion without creating stacking context. */ + backface-visibility: hidden; + background: green; + position: sticky; + top: 0; + width: 100px; + height: 100px; +} + +.spacer { + height: 200vh; +} +</style> +<div class="marker"></div> + +<div class="sticky"></div> +<div class="spacer"></div> + +<script> +requestAnimationFrame(() => { + requestAnimationFrame(() => { + document.querySelector('.sticky').style.setProperty('top', '200px'); + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); + takeScreenshot(); + }); +}); +</script> +</html> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-child-multicolumn-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-child-multicolumn-ref.html new file mode 100644 index 0000000000..ccbeaa8ca7 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-child-multicolumn-ref.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<title>Reference for multicolumn under position:sticky should be positioned correctly</title> +<style> + body { + margin: 0; + } + #scroller { + overflow-y: scroll; + width: 200px; + height: 200px; + } + #relative { + position: relative; + top: 100px; + margin: 10px; + } + #child { + width: 100px; + height: 100px; + background: green; + } + #contents { + position: relative; + top: 10%; + left: 10%; + width: 80%; + height: 80%; + background: lightgreen; + } + #spacer { + height: 400px; + } +</style> + +<div id="scroller"> + <div id="relative"> + <div id="child"> + <div id="contents"></div> + </div> + </div> + <div id="spacer"></div> +</div> + +<div>You should see a light green box above with a dark green border, no blue should be visible.</div> + +<script> + window.addEventListener('load', function() { + scroller.scrollTop = 100; + }); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-child-multicolumn.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-child-multicolumn.html new file mode 100644 index 0000000000..14bb695f1a --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-child-multicolumn.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<title>Multicolumn under position:sticky should be positioned correctly</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<link rel="match" href="position-sticky-child-multicolumn-ref.html" /> +<link rel="author" title="Philip Rogers" href="mailto:pdr@chromium.org" /> +<meta name="assert" content="This test checks that a multicolumn element is positioned relative to a sticky position" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> + body { + margin: 0; + } + #scroller { + overflow-y: scroll; + width: 200px; + height: 200px; + } + #sticky { + position: sticky; + top: 10px; + margin: 10px; + } + #multicolumn { + width: 100px; + height: 100px; + background: green; + columns: 1; + } + #contents { + margin-left: 10%; + margin-top: 10%; + width: 80%; + height: 80%; + background: lightgreen; + } + #spacer { + height: 400px; + } +</style> + +<div id="scroller"> + <div id="sticky"> + <div id="multicolumn"> + <div id="contents"></div> + </div> + </div> + <div id="spacer"></div> +</div> + +<div>You should see a light green box above with a dark green border, no blue should be visible.</div> + +<script> + window.addEventListener('load', function() { + scroller.scrollTop = 100; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); + }); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-contained-by-display-table-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-contained-by-display-table-ref.html new file mode 100644 index 0000000000..32115516ef --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-contained-by-display-table-ref.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<title>position:sticky should work for elements with display: table* containing blocks</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky works for elements with containing blocks that have display: table*" /> + +<style> +.group { + display: inline-block; +} + +.container { + height: 1000px; + width: 50px; + margin-right: 10px; +} + +.scroll-container { + height: 300px; + width: 500px; + overflow: hidden; +} + +.sticky { + height: 50px; + width: 50px; + background: green; +} +</style> + +<div class="scroll-container"> + <div class="group"> + <div class="container" style="display: table-cell;"> + <div class="sticky"></div> + </div> + </div> + + <div class="group"> + <div class="container" style="display: table-row;"> + <div class="sticky"></div> + </div> + </div> + + <div class="group"> + <div class="container" style="display: table;"> + <div class="sticky"></div> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-contained-by-display-table.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-contained-by-display-table.html new file mode 100644 index 0000000000..e9c016e938 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-contained-by-display-table.html @@ -0,0 +1,71 @@ +<!DOCTYPE html> +<title>position:sticky should work for elements with display: table* containing blocks</title> +<link rel="match" href="position-sticky-contained-by-display-table-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky works for elements with containing blocks that have display: table*" /> + +<style> +.group { + display: inline-block; +} + +.container { + height: 1000px; + width: 50px; + margin-right: 10px; +} + +#scroll-container { + height: 300px; + width: 500px; + overflow: hidden; + position: relative; +} + +.sticky { + position: sticky; + height: 50px; + width: 50px; + background: green; + top: 0; +} + +#scroll-indicator { + display: inline-block; + position: absolute; + top: 0px; + width: 300px; + height: 50px; + background: red; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroll-container').scrollTop = 300; +}); +</script> + + +<div id="scroll-container"> + <div class="group"> + <div class="container" style="display: table-cell;"> + <div class="sticky"></div> + </div> + </div> + + <div class="group"> + <div class="container" style="display: table-row;"> + <div class="sticky"></div> + </div> + </div> + + <div class="group"> + <div class="container" style="display: table;"> + <div class="sticky"></div> + </div> + </div> + + <!-- This is here to validate that the container does scroll. --> + <div id="scroll-indicator" style=""></div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-001-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-001-ref.html new file mode 100644 index 0000000000..0d760d18dc --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-001-ref.html @@ -0,0 +1,2 @@ +<!DOCTYPE html> +<div style="width: 200px; height: 200px; background: green"></div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-001.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-001.html new file mode 100644 index 0000000000..dd58327388 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-001.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>CSS Positioned Layout Test: a sticky element contained by fixed under a scroller not containing fixed</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> +<link rel="help" href="https://crbug.com/881555"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3185"> +<link rel="match" href="position-sticky-escape-scroller-001-ref.html"> +<div id="scroller" style="width: 200px; height: 100px; overflow: hidden"> + <div style="height: 100px; background: red"></div> + <div style="position: fixed; height: 400px"> + <div style="position: sticky; top: 0; width: 200px; height: 100px; background: green"></div> + </div> + <div style="height: 100px; background: red"></div> + <div style="height: 100px; background: green"></div> + <div style="height: 1000px; background: red"></div> +</div> +<script> +scroller.scrollTop = 200; +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-002-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-002-ref.html new file mode 100644 index 0000000000..2fa0a2a9ed --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-002-ref.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<style>body { margin: 0 }</style> +<div style="height: 3200px"></div> +<div style="position: fixed; top: 100px; left: 0; + width: 200px; height: 200px; background: green"></div> +<script> +window.scrollTo(0, 2000); +</script> + diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-002.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-002.html new file mode 100644 index 0000000000..225012b9ec --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-002.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>CSS Positioned Layout Test: a sticky element contained by fixed under a scroller not containing fixed</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> +<link rel="help" href="https://crbug.com/881555"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3185"> +<link rel="match" href="position-sticky-escape-scroller-002-ref.html"> +<style>body { margin: 0 }</style> +<div id="scroller" style="width: 200px; height: 200px; overflow: scroll"> + <div style="position: fixed; top: 100px; height: 2000px"> + <div style="position: sticky; top: 0; width: 200px; height: 200px; background: green"></div> + </div> + <div style="height: 1000px; background: red"></div> +</div> +<div style="height: 3000px"></div> +<script> +window.scrollTo(0, 2000); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-003.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-003.html new file mode 100644 index 0000000000..434b279705 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-003.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>CSS Positioned Layout Test: a sticky element contained by absolute under a scroller not containing absolute</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> +<link rel="help" href="https://crbug.com/881555"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3185"> +<link rel="match" href="position-sticky-escape-scroller-001-ref.html"> +<div id="scroller" style="width: 200px; height: 100px; overflow: hidden"> + <div style="height: 100px; background: red"></div> + <div style="position: absolute; height: 400px"> + <div style="position: sticky; top: 0; width: 200px; height: 100px; background: green"></div> + </div> + <div style="height: 100px; background: red"></div> + <div style="height: 100px; background: green"></div> + <div style="height: 1000px; background: red"></div> +</div> +<script> +scroller.scrollTop = 200; +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-004-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-004-ref.html new file mode 100644 index 0000000000..fa9f2b7dc0 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-004-ref.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<style>body { margin: 0 }</style> +<div style="height: 3200px"></div> +<div style="position: fixed; top: 0; left: 0; + width: 200px; height: 200px; background: green"></div> +<script> +window.scrollTo(0, 1000); +</script> + diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-004.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-004.html new file mode 100644 index 0000000000..ed14d62ac4 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-escape-scroller-004.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>CSS Positioned Layout Test: a sticky element contained by absolute under a scroller not containing absolute</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> +<link rel="help" href="https://crbug.com/881555"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3185"> +<link rel="match" href="position-sticky-escape-scroller-004-ref.html"> +<style>body { margin: 0 }</style> +<div id="scroller" style="width: 200px; height: 200px; overflow: scroll"> + <div style="position: absolute; top: 100px; height: 2000px"> + <div style="position: sticky; top: 0; width: 200px; height: 200px; background: green"></div> + </div> + <div style="height: 1000px; background: red"></div> +</div> +<div style="height: 3000px"></div> +<script> +window.scrollTo(0, 1000); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-002.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-002.html new file mode 100644 index 0000000000..dc3c383ea5 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-002.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Positioned Layout Test: a sticky element inside a fixed ancestor</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="match" href="reference/position-sticky-fixed-ancestor-002-ref.html"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + + <meta name="flags" content=""> + + <style> + html, body, div + { + height: 100%; + margin: 0; + width: 100%; + } + + div#positioned-container + { + background-color: red; + color: yellow; + font-size: 40vh; + position: absolute; + } + + div#sticky + { + background-color: green; + bottom: 0; + color: white; + position: sticky; + } + </style> + + <script type="text/javascript"> + function startTest() + { + document.getElementById("positioned-container").style.position = "fixed"; + } + </script> + + <body onload="startTest();"> + + <div id="positioned-container"> + + <div id="vertical-spacer">FAIL</div> + + <div id="sticky">PASS</div> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-003.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-003.html new file mode 100644 index 0000000000..382112cae4 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-003.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Positioned Layout Test: a sticky element inside a fixed ancestor</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="match" href="reference/position-sticky-fixed-ancestor-002-ref.html"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + + <meta name="flags" content=""> + + <style> + html, body, div + { + height: 100%; + margin: 0; + width: 100%; + } + + div#fixed-container + { + background-color: red; + color: yellow; + font-size: 40vh; + position: fixed; + } + + div#sticky + { + background-color: green; + bottom: 0; + color: white; + position: sticky; + } + </style> + + <div id="fixed-container"> + + <div id="vertical-spacer">FAIL</div> + + <div id="sticky">PASS</div> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-iframe-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-iframe-ref.html new file mode 100644 index 0000000000..37372ceca1 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-iframe-ref.html @@ -0,0 +1,93 @@ +<!DOCTYPE html> +<title>Sticky elements inside fixed ancestors and iframe shouldn't account for scroll</title> + +<style> + body,html { + margin: 0; + width: 100%; + height: 100%; + } + + iframe { + margin: 10px; + width: 90%; + height: 90%; + border: 1px solid black; + } + + .spacer { + height: 120vh; + } +</style> + +<div class="spacer"></div> +<iframe srcdoc=" + <!DOCTYPE html> + <title>Reference for sticky elements inside fixed ancestors shouldn't account for scroll</title> + <style> + body,html { + margin: 0; + width: 100%; + height: 100%; + } + + .sticky { + background: green; + width: 100px; + height: 10%; + } + + .spacer { + height: calc(25vh - 10%); + } + .long { + height: 600vh; + } + + .position-parent { + position: absolute; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + top: 100vh; + background-color: lightgrey; + } + + .container { + width: 100px; + height: 100%; + background-color: grey; + } + + button { + position: fixed; + left: 20px; + top: 20px; + } + + .fixed { + position: fixed; + top: 25vh; + } + </style> + + <div class='position-parent fixed'> + <div class='container'> + <div class='spacer'></div> + <div class='sticky'></div> + </div> + </div> + <div class='long'></div> + <button id='button'>Toggle Fixed</button> + <script> + window.scrollTo(0, document.querySelector('.long').clientHeight); + </script> +"></iframe> +<div class="spacer"></div> + +<script> + const child = document.querySelector('iframe'); + child.scrollIntoView(); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-iframe.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-iframe.html new file mode 100644 index 0000000000..e50f5c829b --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-iframe.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<html class='reftest-wait'> +<title>Sticky elements inside fixed ancestors and iframe shouldn't account for scroll</title> +<link rel="match" href="position-sticky-fixed-ancestor-iframe-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<link rel="help" href="https://crbug.com/1019142"> +<meta name="assert" content="This test checks that a sticky element inside a fixed subtree and iframe doesn't scroll with the viewport "/> + +<script src="/common/reftest-wait.js"></script> + +<style> + body,html { + margin: 0; + width: 100%; + height: 100%; + } + + iframe { + margin: 10px; + width: 90%; + height: 90%; + border: 1px solid black; + } + + .spacer { + height: 120vh; + } +</style> + +<div class="spacer"></div> +<iframe src="../resources/position-sticky-fixed-ancestor-iframe-child.html"></iframe> +<div class="spacer"></div> + +<script> + const child = document.querySelector('iframe'); + child.scrollIntoView(); + window.onload = () => { + const childDoc = child.contentDocument; + function toggleFixed() { + childDoc.querySelector('.position-parent').classList.toggle('fixed'); + } + + childDoc.getElementById('button').addEventListener('click', toggleFixed); + + requestAnimationFrame(() => { + childDoc.scrollingElement.scrollTop = childDoc.querySelector('.long').clientHeight; + requestAnimationFrame(() => { + toggleFixed(); + takeScreenshot(); + }); + }); + }; +</script> +</html> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-ref.html new file mode 100644 index 0000000000..fe404b5bab --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor-ref.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<title>Reference for sticky elements inside fixed ancestors shouldn't account for scroll</title> +<style> + body,html { + margin: 0; + width: 100%; + height: 100%; + } + + .sticky { + background: green; + width: 100px; + height: 10%; + } + + .spacer { + height: calc(25vh - 10%); + } + .long { + height: 600vh; + } + + .position-parent { + position: absolute; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + top: 100vh; + background-color: lightgrey; + } + + .container { + width: 100px; + height: 100%; + background-color: grey; + } + + button { + position: fixed; + left: 20px; + top: 20px; + } + + .fixed { + position: fixed; + top: 25vh; + } +</style> + +<div>You should see a green box below. No blue should be visible.</div> +<div class="position-parent fixed"> + <div class="container"> + <div class="spacer"></div> + <div class="sticky"></div> + </div> +</div> +<div class="long"></div> +<button id="button">Toggle Fixed</button> + +<script> + window.scrollTo(0, document.querySelector('.long').clientHeight); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor.html new file mode 100644 index 0000000000..52760992b1 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-fixed-ancestor.html @@ -0,0 +1,89 @@ +<!DOCTYPE html> +<html class='reftest-wait'> +<title>Sticky elements inside fixed ancestors shouldn't account for scroll</title> +<link rel="match" href="position-sticky-fixed-ancestor-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<link rel="help" href="https://crbug.com/1019142"> +<meta name="assert" content="This test checks that a sticky element inside a fixed subtree doesn't scroll with the viewport "/> + +<script src="/common/reftest-wait.js"></script> +<script src="../resources/ref-rectangle.js"></script> + + +<style> + body,html { + margin: 0; + width: 100%; + height: 100%; + } + + .sticky { + background: green; + position: sticky; + bottom: 50vh; + width: 100px; + height: 10%; + } + + .spacer { + height: 90%; + } + .long { + height: 600vh; + } + + .position-parent { + position: absolute; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + top: 100vh; + background-color: lightgrey; + } + + .container { + width: 100px; + height: 100%; + background-color: grey; + } + + button { + position: fixed; + left: 20px; + top: 20px; + } + + .fixed { + position: fixed; + top: 25vh; + } +</style> + +<div>You should see a green box below. No blue should be visible.</div> +<div class="position-parent"> + <div class="container"> + <div class="spacer"></div> + <div class="sticky"></div> + </div> +</div> +<div class="long"></div> +<button id="button">Toggle Fixed</button> +<script> + function toggleFixed() { + document.querySelector('.position-parent').classList.toggle('fixed'); + } + + document.getElementById('button').addEventListener('click', toggleFixed); + + requestAnimationFrame(() => { + window.scrollTo(0, document.querySelector('.long').clientHeight); + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); + requestAnimationFrame(() => { + toggleFixed(); + takeScreenshot(); + }); + }); +</script> +</html> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-001.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-001.html new file mode 100644 index 0000000000..1b1f9d0afb --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-001.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com"> +<link rel="author" title="Mozilla" href="https://www.mozilla.org"> +<link rel="help" href="https://drafts.csswg.org/css-position-3/#stickypos-insets"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1377072"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<meta name="assert" content="This test verifies that the sticky flex item reserves its in-flow space in the scroll container's overflow area."> + +<style> +#flex-scroller { + overflow: hidden; + inline-size: 100px; + block-size: 100px; + display: flex; + flex-direction: column; + background-color: green; +} + +#non-sticky { + flex: 0 0 80px; + background-color: red; +} + +#sticky { + position: sticky; + flex: 0 0 100px; + bottom: 0; +} +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div id="flex-scroller"> + <div id="non-sticky"></div> + <div id="sticky"></div> +</div> + +<script> +// Scroll the scroll container down to the bottom. +document.getElementById("flex-scroller").scrollTop="1000"; +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-002.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-002.html new file mode 100644 index 0000000000..5b4c81df67 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-002.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com"> +<link rel="author" title="Mozilla" href="https://www.mozilla.org"> +<link rel="help" href="https://drafts.csswg.org/css-position-3/#stickypos-insets"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1377072"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<meta name="assert" content="This test verifies that the sticky flex item reserves its in-flow space in the scroll container's overflow area."> + +<style> +#flex-scroller { + overflow: hidden; + inline-size: 100px; + block-size: 100px; + display: flex; + flex-direction: row; + background-color: green; +} + +#non-sticky { + flex: 0 0 80px; + background-color: red; +} + +#sticky { + position: sticky; + flex: 0 0 100px; + right: 0; +} +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div id="flex-scroller"> + <div id="non-sticky"></div> + <div id="sticky"></div> +</div> + +<script> +// Scroll the scroll container to the far right. +document.getElementById("flex-scroller").scrollLeft="1000"; +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-003.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-003.html new file mode 100644 index 0000000000..50e0e25980 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-003.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com"> +<link rel="author" title="Mozilla" href="https://www.mozilla.org"> +<link rel="help" href="https://drafts.csswg.org/css-position-3/#stickypos-insets"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1377072"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<meta name="assert" content="This test verifies that the sticky flex item reserves its in-flow space in the scroll container's overflow area."> + +<style> +#scroller { + overflow: hidden; + inline-size: 100px; + block-size: 100px; + background-color: green; +} + +#flex { + display: flex; + flex-direction: column; + + /* Use a small block-size so that the flex items overflow the flex container. + It's necessary to trigger the bug. */ + block-size: 10px; +} + +#non-sticky { + flex: 0 0 80px; + background-color: red; +} + +#sticky { + position: sticky; + flex: 0 0 100px; + bottom: 0; +} +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div id="scroller"> + <div id="flex"> + <div id="non-sticky"></div> + <div id="sticky"></div> + </div> +</div> + +<script> +// Scroll the scroll container down to the bottom. +document.getElementById("scroller").scrollTop="1000"; +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-004.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-004.html new file mode 100644 index 0000000000..68b933a319 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flex-item-004.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com"> +<link rel="author" title="Mozilla" href="https://www.mozilla.org"> +<link rel="help" href="https://drafts.csswg.org/css-position-3/#stickypos-insets"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1377072"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<meta name="assert" content="This test verifies that the sticky flex item reserves its in-flow space in the scroll container's overflow area."> + +<style> +#scroller { + overflow: hidden; + inline-size: 100px; + block-size: 100px; + background-color: green; +} + +#flex { + display: flex; + flex-direction: row; + + /* Use a small inline-size so that the flex items overflow the flex container. + It's necessary to trigger the bug. */ + inline-size: 10px; + block-size: 100px; +} + +#non-sticky { + flex: 0 0 80px; + background-color: red; +} + +#sticky { + position: sticky; + flex: 0 0 100px; + right: 0; +} +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div id="scroller"> + <div id="flex"> + <div id="non-sticky"></div> + <div id="sticky"></div> + </div> +</div> + +<script> +// Scroll the scroll container to the far right. +document.getElementById("scroller").scrollLeft="1000"; +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-flexbox-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flexbox-ref.html new file mode 100644 index 0000000000..b78c784de1 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flexbox-ref.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<title>Reference for position:sticky elements should work correctly with flexbox</title> + +<style> +.scroller { + overflow: scroll; + width: 350px; + height: 100px; + margin-bottom: 15px; +} + +.flex-container { + width: 600px; + position: relative; + display: flex; + flex-flow: row wrap; +} + +.green { + background-color: green; +} + +.flex-item { + height: 85px; + width: 100px; + display: flex; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 50; + document.getElementById('scroller2').scrollLeft = 150; + document.getElementById('scroller3').scrollLeft = 250; +}); +</script> + +<p>You should see three green boxes of varying size below. There should be no red or blue.</p> + +<div id="scroller1" class="scroller"> + <div class="flex-container"> + <div class="flex-item"></div> + <div class="green flex-item"></div> + <div class="green flex-item"></div> + </div> +</div> + +<div id="scroller2" class="scroller"> + <div class="flex-container"> + <div class="flex-item"></div> + <div class="flex-item"></div> + <div class="green flex-item"></div> + </div> +</div> + +<div id="scroller3" class="scroller"> + <div class="flex-container"> + <div class="flex-item"></div> + <div class="flex-item"></div> + <div class="green flex-item"></div> + <div class="green flex-item"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-flexbox.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flexbox.html new file mode 100644 index 0000000000..951de1e71c --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-flexbox.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<title>position:sticky elements should work correctly with flexbox</title> +<link rel="match" href="position-sticky-flexbox-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements interoperate correctly with flexbox" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +.scroller { + overflow: scroll; + width: 350px; + height: 100px; + margin-bottom: 15px; +} + +.flex-container { + width: 600px; + position: relative; + display: flex; + flex-flow: row wrap; +} + +.sticky { + position: sticky; + left: 50px; +} + +.green { + background-color: green; +} + +.flex-item { + width: 100px; + height: 85px; + display: flex; +} + +.indicator { + position: absolute; + background-color: red; + width: 100px; + height: 85px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 50; + document.getElementById('scroller2').scrollLeft = 150; + document.getElementById('scroller3').scrollLeft = 250; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<p>You should see three green boxes of varying size below. There should be no red or blue.</p> + +<div id="scroller1" class="scroller"> + <div class="flex-container"> + <div class="indicator" style="left: 100px;"></div> + <div class="flex-item"></div> + <div class="sticky green flex-item"></div> + <div class="green flex-item"></div> + </div> +</div> + +<div id="scroller2" class="scroller"> + <div class="flex-container"> + <div class="indicator" style="left: 200px;"></div> + <div class="flex-item"></div> + <div class="sticky green flex-item"></div> + <div class="green flex-item"></div> + </div> +</div> + +<div id="scroller3" class="scroller"> + <div class="flex-container"> + <div class="indicator" style="left: 300px;"></div> + <div class="flex-item"></div> + <div class="sticky green flex-item"></div> + <div class="green flex-item"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-get-bounding-client-rect.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-get-bounding-client-rect.html new file mode 100644 index 0000000000..18b2acfe16 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-get-bounding-client-rect.html @@ -0,0 +1,99 @@ +<!DOCTYPE html> +<title>Sticky positioned element should be observable by getBoundingClientRect.</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that sticky positioned element +should be observable by getBoundingClientRect." /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +body { + margin: 0; +} + +.container { + overflow: scroll; + width: 200px; + height: 200px; +} + +.spacer { + width: 2000px; + height: 2000px; +} + +.box { + width: 100px; + height: 100px; + background-color: green; +} + +.sticky { + position: sticky; + top: 50px; + left: 20px; +} +</style> + +<div id="scroller1" class="container"> + <div id="sticky1" class="sticky box"></div> + <div class="spacer"></div> +</div> + +<script> +test(() => { + var sticky = document.getElementById('sticky1'); + assert_equals(sticky.getBoundingClientRect().top, 50); + document.getElementById('scroller1').scrollTop = 100; + assert_equals(sticky.getBoundingClientRect().top, 50); + sticky.style.position = 'relative'; + assert_equals(sticky.getBoundingClientRect().top, -50); + sticky.style.position = 'sticky'; + assert_equals(sticky.getBoundingClientRect().top, 50); +}, 'sticky positioned element should be observable by getBoundingClientRect.'); +</script> + +<div id="scroller2" class="container"> + <div class="spacer"></div> +</div> + +<script> +test(() => { + var scroller = document.getElementById('scroller2'); + scroller.scrollTop = 100; + scroller.scrollLeft = 75; + + var sticky = document.createElement('div'); + sticky.className = 'sticky box'; + scroller.insertBefore(sticky, scroller.querySelector('.spacer')); + + var sticky_bounds = sticky.getBoundingClientRect(); + var scroller_bounds = scroller.getBoundingClientRect(); + assert_equals(sticky_bounds.top, scroller_bounds.top + 50); + assert_equals(sticky_bounds.left, scroller_bounds.left + 20); +}, 'getBoundingClientRect should be correct for sticky after script insertion'); +</script> + +<div id="scroller3" class="container"> + <div id="sticky3" class="sticky box"></div> + <div class="spacer"></div> +</div> + +<script> +test(() => { + var scroller = document.getElementById('scroller3'); + var sticky = document.getElementById('sticky3'); + scroller.scrollTop = 100; + scroller.scrollLeft = 75; + + var div = document.createElement('div'); + div.style.height = '65px'; + scroller.insertBefore(div, sticky); + + var sticky_bounds = sticky.getBoundingClientRect(); + var scroller_bounds = scroller.getBoundingClientRect(); + assert_equals(sticky_bounds.top, scroller_bounds.top + 50); + assert_equals(sticky_bounds.left, scroller_bounds.left + 20); +}, 'getBoundingClientRect should be correct for sticky after script-caused layout'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-grid-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-grid-ref.html new file mode 100644 index 0000000000..123eed311b --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-grid-ref.html @@ -0,0 +1,76 @@ +<!DOCTYPE html> +<title>Reference for position:sticky elements should work correctly with grid layout</title> + +<style> +.scroller { + position: relative; + overflow-x: scroll; + overflow-y: hidden; + width: 300px; + height: 100px; + margin-bottom: 15px; +} + +.grid-container { + display: grid; + grid-template-columns: 25% 25% 25% 25%; + grid-template-rows: 100%; + width: 400px; + height: 90px; +} + +.green { + background-color: green; +} + +.grid-item { + width: 100%; + height: 100%; + grid-row: 1; +} + +.padding { + height: 1px; + width: 700px; +} + +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 0; + document.getElementById('scroller2').scrollLeft = 150; + document.getElementById('scroller3').scrollLeft = 300; +}); +</script> + +<p>You should see three green boxes of varying size below. There should be no red or blue.</p> + +<div id="scroller1" class="scroller"> + <div class="grid-container"> + <div class="grid-item" style="grid-column: 1;"></div> + <div class="green grid-item" style="grid-column: 2;"></div> + <div class="green grid-item" style="grid-column: 3;"></div> + </div> + <div class="padding"></div> +</div> + +<div id="scroller2" class="scroller"> + <div class="grid-container"> + <div class="grid-item" style="grid-column: 1;"></div> + <div class="grid-item" style="grid-column: 2;"></div> + <div class="green grid-item" style="grid-column: 3;"></div> + </div> + <div class="padding"></div> +</div> + +<div id="scroller3" class="scroller"> + <div class="grid-container"> + <div class="grid-item" style="grid-column: 1;"></div> + <div class="grid-item" style="grid-column: 2;"></div> + <div class="grid-item" style="grid-column: 3;"></div> + <div class="green grid-item" style="grid-column: 4;"></div> + </div> + <div class="padding"></div> +</div> + diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-grid.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-grid.html new file mode 100644 index 0000000000..607e7c2936 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-grid.html @@ -0,0 +1,95 @@ +<!DOCTYPE html> +<title>position:sticky elements should work correctly with grid layout</title> +<link rel="match" href="position-sticky-grid-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements interoperate correctly with grid" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +.scroller { + position: relative; + overflow-x: scroll; + overflow-y: hidden; + width: 300px; + height: 100px; + margin-bottom: 15px; +} + +.grid-container { + display: grid; + grid-template-columns: 25% 25% 25% 25%; + grid-template-rows: 100%; + width: 400px; + height: 90px; +} + +.sticky { + position: sticky; + left: 50px; +} + +.green { + background-color: green; +} + +.grid-item { + width: 100%; + height: 100%; + grid-row: 1; +} + +.indicator { + position: absolute; + background-color: red; + width: 100px; + height: 90px; +} + +.padding { + height: 1px; + width: 700px; +} + +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 0; + document.getElementById('scroller2').scrollLeft = 150; + document.getElementById('scroller3').scrollLeft = 300; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<p>You should see three green boxes of varying size below. There should be no red or blue.</p> + +<div id="scroller1" class="scroller"> + <div class="grid-container"> + <div class="indicator" style="left: 100px;"></div> + <div class="grid-item" style="grid-column: 1;"></div> + <div class="sticky green grid-item" style="grid-column: 2;"></div> + <div class="green grid-item" style="grid-column: 3;"></div> + </div> + <div class="padding"></div> +</div> + +<div id="scroller2" class="scroller"> + <div class="grid-container"> + <div class="indicator" style="left: 200px;"></div> + <div class="grid-item" style="grid-column: 1;"></div> + <div class="sticky green grid-item" style="grid-column: 2;"></div> + <div class="green grid-item" style="grid-column: 3;"></div> + </div> + <div class="padding"></div> +</div> + +<div id="scroller3" class="scroller"> + <div class="grid-container"> + <div class="indicator" style="left: 300px;"></div> + <div class="grid-item" style="grid-column: 1;"></div> + <div class="sticky green grid-item" style="grid-column: 2;"></div> + <div class="green grid-item" style="grid-column: 3;"></div> + </div> + <div class="padding"></div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-hyperlink-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-hyperlink-ref.html new file mode 100644 index 0000000000..88d45a7e6d --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-hyperlink-ref.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<title>Reference for sticky hyperlink should work on high dpi devices</title> + +<style> +body { + margin: 0; +} + +.scroller { + overflow: scroll; + width: 200px; + height: 200px; +} + +.positioned { + position: relative; + top: 100px; + will-change: transform; +} + +.spacer { + height: 700px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.querySelector('.scroller').scrollTop = 100; +}); +</script> + +<div>You should see a sticky link at the top of the scrollable area.</div> + +<div class='scroller'> + <a href='#' class='positioned'>Link</a> + <div class='spacer'></div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-hyperlink.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-hyperlink.html new file mode 100644 index 0000000000..c8ef07edd1 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-hyperlink.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<title>Sticky element with hyperlink should work</title> +<link rel="match" href="position-sticky-hyperlink-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that sticky hyperlink works." /> + +<style> +body { + margin: 0; +} + +.scroller { + overflow: scroll; + width: 200px; + height: 200px; +} + +.sticky { + position: sticky; + top: 0; + will-change: transform; +} + +.spacer { + height: 700px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.querySelector('.scroller').scrollTop = 100; +}); +</script> + +<div>You should see a sticky link at the top of the scrollable area.</div> + +<div class='scroller'> + <a href='#' class='sticky'>Link</a> + <div class='spacer'></div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-inflow-position.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-inflow-position.html new file mode 100644 index 0000000000..a6774b7a71 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-inflow-position.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<title>position:sticky elements should not affect the flow position of other elements</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements do not affect the flow position of other elements" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +.scroller { + position: relative; + height: 200px; + width: 100px; + overflow: scroll; +} + +#sticky { + background-color: green; + position: sticky; + top: 150px; +} + +#before { + background-color: fuchsia; +} + +#after { + background-color: orange; +} + +.box { + height: 50px; + width: 50px; +} + +.padding { + height: 500px; +} +</style> + +<div class="scroller"> + <div id="before" class="box"></div> + <div id="sticky" class="box"></div> + <div id="after" class="box"></div> + <div class="padding"></div> +</div> + +<script> +test(() => { + // The sticky element is pushed to be stuck 150 pixels from the top. + assert_equals(sticky.offsetTop, 150); + + // Neither 'before' or 'after' should be affected by the change in the sticky + // element's location. + assert_equals(before.offsetTop, 0); + assert_equals(after.offsetTop, before.clientHeight + sticky.clientHeight); +}, 'sticky offset should not affect the position of other elements.'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-inline-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-inline-ref.html new file mode 100644 index 0000000000..d3b4869afe --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-inline-ref.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<title>Reference for position:sticky should work for inline elements</title> + +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 250px; +} + +.scroller { + position: relative; + width: 100px; + height: 200px; + overflow-x: hidden; + overflow-y: auto; + font: 25px/1 Ahem; +} + +.contents { + height: 500px; +} + +.indicator { + position: absolute; + left: 0; + color: green; +} + +.inline { + display: inline; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div>You should see three green rectangles below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="contents"> + <div class="indicator inline" style="top: 150px;">XXX</div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="contents"> + <div class="indicator inline" style="top: 175px;">XXX</div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="contents"> + <div class="indicator inline" style="top: 275px;">XXX</div> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-inline.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-inline.html new file mode 100644 index 0000000000..6bd49befe5 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-inline.html @@ -0,0 +1,109 @@ +<!DOCTYPE html> +<title>position:sticky should work for inline elements</title> +<link rel="match" href="position-sticky-inline-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky works for inline elements" /> + +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 250px; +} + +.scroller { + position: relative; + width: 100px; + height: 200px; + overflow-x: hidden; + overflow-y: auto; + font: 25px/1 Ahem; +} + +.contents { + height: 500px; +} + +.prepadding { + height: 100px; +} + +.container { + height: 200px; +} + +.innerpadding { + height: 50px; +} + +.indicator { + position: absolute; + left: 0; + color: red; +} + +.sticky { + position: sticky; + top: 50px; + color: green; +} + +.inline { + display: inline; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see three green rectangles below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator inline" style="top: 150px;">XXX</div> + <div class="contents"> + <div class="prepadding"></div> + <div class="container"> + <div class="innerpadding"></div> + <div class="sticky inline">XXX</div> + </div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator inline" style="top: 175px;">XXX</div> + <div class="contents"> + <div class="prepadding"></div> + <div class="container"> + <div class="innerpadding"></div> + <div class="sticky inline">XXX</div> + </div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator inline" style="top: 275px;">XXX</div> + <div class="contents"> + <div class="prepadding"></div> + <div class="container"> + <div class="innerpadding"></div> + <div class="sticky inline">XXX</div> + </div> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-input-box-gets-focused-after-scroll.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-input-box-gets-focused-after-scroll.html new file mode 100644 index 0000000000..438547dbb7 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-input-box-gets-focused-after-scroll.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<title>Focusing on visible sticky input box should scroll to unshifted sticky position.</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that focusing on visible sticky +positioned input box should not scroll the page." /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +body { + height: 2000px; +} + +input { + position: sticky; + top: 10px; +} +</style> + +<input type="text" id="input"/> + +<script> +test(() => { + var input = document.getElementById('input'); + window.scrollTo(0, 100); + input.focus(); + assert_equals(window.scrollY, 0); +}, 'Focusing on visible sticky input box should reset the scroll to unshifted sticky position.'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top-2-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top-2-ref.html new file mode 100644 index 0000000000..1890063fb9 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top-2-ref.html @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<html> + <meta charset="utf-8"> + <title>CSS Position Test Reference: Test position:sticky element with large top in an overflow scroll container</title> + <link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com"> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/"> + + <style> + .scroll { + border: 5px solid blue; + padding: 5px 3px 0 8px; + overflow: auto; + height: 200px; + width: 200px; + position: relative; + } + + .block { + width: 150px; + height: 200px; + background: yellow; + position: absolute; + top: 55px; + } + + .sticky { + position: absolute; + background: purple; + width: 50px; + height: 50px; + top: 205px; + z-index: 1; + } + </style> + <script> + function runTest() { + document.getElementById("scroll2").scrollTop = 50; + } + </script> + + <body onload="runTest();"> + <div class="scroll"> + <span> + <div class="sticky"></div> + </span> + <div class="block"></div> + </div> + + <div class="scroll" id="scroll2"> + <span> + <div class="sticky"></div> + </span> + <div class="block"></div> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top-2.tentative.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top-2.tentative.html new file mode 100644 index 0000000000..1cf9c0dfb4 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top-2.tentative.html @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<html> + <meta charset="utf-8"> + <title>CSS Position Test: Test position:sticky element with large top in an overflow container</title> + <link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com"> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/"> + <link rel="help" href="https://drafts.csswg.org/css-position/#sticky-pos"> + <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1598112"> + <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2794"> + <link rel="match" href="position-sticky-large-top-2-ref.html"> + <meta name="assert" content="This test verifies the position of a position:sticky element with large top value can be reached by scrolling the overflow container."> + + <style> + .scroll { + border: 5px solid blue; + padding: 5px 3px 0 8px; + overflow: auto; + height: 200px; + width: 200px; + } + + .block { + width: 150px; + height: 200px; + background: yellow; + } + + .sticky { + position: sticky; + background: purple; + width: 50px; + height: 50px; + top: 200px; + } + </style> + <script> + function runTest() { + document.getElementById("scroll2").scrollTop = 50; + } + </script> + + <body onload="runTest();"> + <!-- test before scroll --> + <div class="scroll"> + <span> + <div class="sticky"></div> + </span> + <div class="block"></div> + </div> + + <!-- test after scroll --> + <div class="scroll" id="scroll2"> + <span> + <div class="sticky"></div> + </span> + <div class="block"></div> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top-ref.html new file mode 100644 index 0000000000..b50bae2260 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top-ref.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html> + <meta charset="utf-8"> + <title>CSS Position Test Reference: Test position:sticky element with large top in an overflow scroll container</title> + <link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com"> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/"> + + <style> + .scroll { + border: 5px solid blue; + overflow: auto; + height: 200px; + width: 200px; + position: relative; + } + + .block { + width: 100%; + height: 200px; + background: yellow; + position: absolute; + top: 50px; + } + + .sticky { + position: absolute; + background: purple; + width: 50px; + height: 50px; + top: 200px; + z-index: 1; + } + </style> + <script> + function runTest() { + document.getElementById("scroll2").scrollTop = 50; + } + </script> + + <body onload="runTest();"> + <div class="scroll"> + <div class="sticky"></div> + <div class="block"></div> + </div> + + <div class="scroll" id="scroll2"> + <div class="sticky"></div> + <div class="block"></div> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top.tentative.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top.tentative.html new file mode 100644 index 0000000000..b00a0d1396 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-large-top.tentative.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<html> + <meta charset="utf-8"> + <title>CSS Position Test: Test position:sticky element with large top in an overflow container</title> + <link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com"> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/"> + <link rel="help" href="https://drafts.csswg.org/css-position/#sticky-pos"> + <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1598112"> + <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2794"> + <link rel="match" href="position-sticky-large-top-ref.html"> + <meta name="assert" content="This test verifies the position of a position:sticky element with large top value can be reached by scrolling the overflow container."> + + <style> + .scroll { + border: 5px solid blue; + overflow: auto; + height: 200px; + width: 200px; + } + + .block { + width: 100%; + height: 200px; + background: yellow; + } + + .sticky { + position: sticky; + background: purple; + width: 50px; + height: 50px; + top: 200px; + } + </style> + <script> + function runTest() { + document.getElementById("scroll2").scrollTop = 50; + } + </script> + + <body onload="runTest();"> + <!-- test before scroll --> + <div class="scroll"> + <div class="sticky"></div> + <div class="block"></div> + </div> + + <!-- test after scroll --> + <div class="scroll" id="scroll2"> + <div class="sticky"></div> + <div class="block"></div> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-left-002.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-left-002.html new file mode 100644 index 0000000000..868b58adb0 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-left-002.html @@ -0,0 +1,96 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Position Test: sticky element with left offset specified with px unit</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + <link rel="match" href="reference/position-sticky-left-002-ref.html"> + + <meta name="flags" content=""> + + <style> + div.scrolling-container + { + background-image: url("support/100x100-red.png"); + background-repeat: no-repeat; + height: 150px; + margin-bottom: 30px; + overflow-y: hidden; + position: static; + white-space: nowrap; + width: 250px; + } + + div#first-scrolling-container + { + background-position: right top; + } + + div#second-scrolling-container + { + background-position: 100px top; + } + + div#third-scrolling-container + { + background-position: 50px top; + } + + div.horizontal-spacer + { + display: inline-block; + height: 100%; + width: 100px; + } + + div.content + { + display: inline-block; + height: 100%; + width: 300px; + } + + div.sticky + { + background-color: green; + display: inline-block; + height: 100px; + left: 100px; + position: sticky; + vertical-align: top; + width: 100px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollLeft = 50; document.getElementById("second-scrolling-container").scrollLeft = 150; document.getElementById("third-scrolling-container").scrollLeft = 300;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <!-- + first-scrolling-container: before reaching the sticking point + --> + + <div id="first-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="first-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> + + <!-- + second-scrolling-container: when reaching the sticking point and beyond + --> + + <div id="second-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="second-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> + + + <div id="third-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="third-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-left-003.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-left-003.html new file mode 100644 index 0000000000..3114981a69 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-left-003.html @@ -0,0 +1,96 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Position Test: sticky element with left offset specified with percentage unit</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + <link rel="match" href="reference/position-sticky-left-002-ref.html"> + + <meta name="flags" content=""> + + <style> + div.scrolling-container + { + background-image: url("support/100x100-red.png"); + background-repeat: no-repeat; + height: 150px; + margin-bottom: 30px; + overflow-y: hidden; + position: static; + white-space: nowrap; + width: 250px; + } + + div#first-scrolling-container + { + background-position: right top; + } + + div#second-scrolling-container + { + background-position: 100px top; + } + + div#third-scrolling-container + { + background-position: 50px top; + } + + div.horizontal-spacer + { + display: inline-block; + height: 100%; + width: 100px; + } + + div.content + { + display: inline-block; + height: 100%; + width: 300px; + } + + div.sticky + { + background-color: green; + display: inline-block; + height: 100px; + left: 40%; + position: sticky; + vertical-align: top; + width: 100px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollLeft = 50; document.getElementById("second-scrolling-container").scrollLeft = 150; document.getElementById("third-scrolling-container").scrollLeft = 300;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <!-- + first-scrolling-container: before reaching the sticking point + --> + + <div id="first-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="first-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> + + <!-- + second-scrolling-container: when reaching the sticking point and beyond + --> + + <div id="second-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="second-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> + + + <div id="third-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="third-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-left.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-left.html new file mode 100644 index 0000000000..1fc2e8f88d --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-left.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<title>position:sticky elements should respect the left constraint</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements obey their left anchor after scrolling" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body></body> + +<script> +test(() => { + const elements = setupStickyTest('left', 50); + elements.scroller.scrollLeft = 100; + const nonStickyLeftX = elements.container.offsetLeft + + elements.filler.clientWidth; + assert_equals(elements.sticky.offsetLeft, nonStickyLeftX); +}, 'before reaching the sticking point the sticky box should not be offset'); + +test(() => { + const elements = setupStickyTest('left', 50); + elements.scroller.scrollLeft = 200; + + // This math actually cancels to sticky.offsetLeft == (scroller.scrollLeft + 50), + // but for clarity the calculations are left explicit. + const nonStickyLeftX = elements.container.offsetLeft + + elements.filler.clientWidth; + const targetLeftX = elements.scroller.scrollLeft + 50; + const stickyOffset = targetLeftX - nonStickyLeftX; + + assert_equals(elements.sticky.offsetLeft, nonStickyLeftX + stickyOffset); +}, 'after reaching the sticking point the sticky box should be offset'); + +test(() => { + const elements = setupStickyTest('left', 50); + elements.scroller.scrollLeft = 300; + const maxOffsetInContainer = elements.container.offsetLeft + + elements.container.clientWidth - elements.sticky.clientWidth; + assert_equals(elements.sticky.offsetLeft, maxOffsetInContainer); +}, 'the sticky box should not be pushed outside its containing block'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-margins.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-margins.html new file mode 100644 index 0000000000..7a9cf09faa --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-margins.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<title>position:sticky elements should properly interact with margins</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="position:sticky elements should ignore margins when sticking, but consider them when making sure sticky elements do not escape their containing block" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body></body> + +<script> +test(() => { + const elements = setupStickyTest('top', 50); + elements.sticky.style.margin = '15px'; + elements.scroller.scrollTop = 100; + assert_equals(elements.sticky.offsetTop, + elements.container.offsetTop + elements.filler.clientHeight + 15); +}, 'Before sticking, the margin should be obeyed.'); + +test(() => { + const elements = setupStickyTest('top', 50); + elements.sticky.style.margin = '15px'; + + elements.scroller.scrollTop = 200; + + // This math cancels to sticky.offsetTop == (scroller.scrollTop + 50), but + // for clarity the calculations are left explicit. + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + const targetTopY = elements.scroller.scrollTop + 50; + const stickyOffset = targetTopY - nonStickyTopY; + + assert_equals(elements.sticky.offsetTop, nonStickyTopY + stickyOffset); +}, 'Whilst stuck, the margin is irrelevant.'); + +test(() => { + const elements = setupStickyTest('top', 50); + elements.sticky.style.margin = '15px'; + + elements.scroller.scrollTop = 300; + + const maxOffsetInContainer = elements.container.offsetTop + + elements.container.clientHeight - elements.sticky.clientHeight; + assert_equals(elements.sticky.offsetTop, maxOffsetInContainer - 15); +}, 'The margin is taken into account when making sure the sticky element ' + + 'does not escape its container'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-bottom.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-bottom.html new file mode 100644 index 0000000000..34fb3b32fc --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-bottom.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<title>Nested bottom-constrained position:sticky elements should render correctly</title> + +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that nested position:sticky elements with a bottom constraint render correctly" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body></body> + +<script> +test(() => { + const elements = setupNestedStickyTest('bottom', 25, 35); + elements.scroller.scrollTop = 300; + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + assert_equals(elements.sticky.offsetTop, nonStickyTopY); + // The inner sticky should not be offset from the outer. + const nonStickyInnerTopY = elements.sticky.clientHeight - + elements.innerSticky.clientHeight; + assert_equals(elements.innerSticky.offsetTop, nonStickyInnerTopY); +}, 'before reaching the sticking point, neither sticky box should be offset'); + +test(() => { + const elements = setupNestedStickyTest('bottom', 25, 50); + elements.scroller.scrollTop = 150; + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + assert_equals(elements.sticky.offsetTop, nonStickyTopY); + assert_equals(elements.innerSticky.offsetTop, 50); +}, 'the inner sticky can stick before the outer one if necessary'); + +test(() => { + const elements = setupNestedStickyTest('bottom', 25, 35); + elements.scroller.scrollTop = 100; + + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + const nonStickyBottomY = nonStickyTopY + elements.sticky.clientHeight; + const targetBottomY = elements.scroller.clientHeight + + elements.scroller.scrollTop - 25; + const stickyOffset = nonStickyBottomY - targetBottomY; + assert_equals(elements.sticky.offsetTop, nonStickyTopY - stickyOffset); + + // The inner sticky has similar math, but its offsetTop is relative to the + // sticky element and in this test is (height - the difference between the + // top values). + assert_equals(elements.innerSticky.offsetTop, 40); +}, 'both sticky boxes can be stuck at the same time'); + +test(() => { + const elements = setupNestedStickyTest('bottom', 25, 75); + elements.scroller.scrollTop = 0; + assert_equals(elements.sticky.offsetTop, elements.container.offsetTop); + assert_equals(elements.innerSticky.offsetTop, 0); +}, 'neither sticky can escape their containing block'); + +test(() => { + const elements = setupNestedStickyTest('bottom', 25, 300); + elements.scroller.scrollTop = 200; + // It doesn't matter how big the inner sticky offset is, it cannot escape its + // containing block (the outer sticky). + assert_equals(elements.innerSticky.offsetTop, 0); +}, 'the inner sticky cannot be pushed outside the outer sticky'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-inline-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-inline-ref.html new file mode 100644 index 0000000000..4ad6dee5d0 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-inline-ref.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<title>Reference for nested inline position:sticky elements should render correctly</title> + +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 250px; +} + +.scroller { + position: relative; + width: 100px; + height: 200px; + overflow-x: hidden; + overflow-y: auto; + font: 25px/1 Ahem; +} + +.contents { + height: 500px; +} + +.outerIndicator { + color: green; + position: absolute; + left: 0; +} + +.innerIndicator { + color: yellow; + position: absolute; + left: 25px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 225; +}); +</script> + +<div>You should see three green and three yellow rectangles below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="contents"> + <div class="outerIndicator" style="top: 150px;">X</div> + <div class="innerIndicator" style="top: 150px;">XX</div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="contents"> + <div class="outerIndicator" style="top: 175px;">X</div> + <div class="innerIndicator" style="top: 185px;">XX</div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="contents"> + <div class="outerIndicator" style="top: 275px;">X</div> + <div class="innerIndicator" style="top: 275px;">XX</div> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-inline.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-inline.html new file mode 100644 index 0000000000..92eda147bd --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-inline.html @@ -0,0 +1,119 @@ +<!DOCTYPE html> +<title>Nested inline position:sticky elements should render correctly</title> +<link rel="match" href="position-sticky-nested-inline-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that nested inline position:sticky elements render correctly" /> + +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 250px; +} + +.scroller { + position: relative; + width: 100px; + height: 200px; + overflow-x: hidden; + overflow-y: auto; + font: 25px/1 Ahem; +} + +.contents { + height: 500px; +} + +.prepadding { + height: 100px; +} + +.container { + height: 200px; +} + +.innerpadding { + height: 50px; +} + +.outerIndicator { + color: red; + position: absolute; + left: 0; +} + +.innerIndicator { + color: red; + position: absolute; + left: 25px; +} + +.outerSticky { + display: inline; + color: green; + position: sticky; + top: 50px; +} + +.innerSticky { + display: inline; + color: yellow; + position: sticky; + top: 60px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 225; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see three green and three yellow rectangles below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="outerIndicator" style="top: 150px;">X</div> + <div class="contents"> + <div class="prepadding"></div> + <div class="container"> + <div class="innerpadding"></div> + <div class="outerSticky">X<div class="innerIndicator" style="top: 0;">XX</div><div class="innerSticky">XX</div></div> + </div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="outerIndicator" style="top: 175px;">X</div> + <div class="contents"> + <div class="prepadding"></div> + <div class="container"> + <div class="innerpadding"></div> + <div class="outerSticky">X<div class="innerIndicator" style="top: 10px;">XX</div><div class="innerSticky">XX</div></div> + </div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="outerIndicator" style="top: 200px;">X</div> + <div class="contents"> + <div class="prepadding"></div> + <div class="container"> + <div class="innerpadding"></div> + <div class="outerSticky">X<div class="innerIndicator" style="top: 0;">XX</div><div class="innerSticky">XX</div></div> + </div> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-left.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-left.html new file mode 100644 index 0000000000..b92d45319b --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-left.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<title>Nested left-constrained position:sticky elements should render correctly</title> + +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that nested position:sticky elements with a left constraint render correctly" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body></body> + +<script> +test(() => { + const elements = setupNestedStickyTest('left', 50, 60); + elements.scroller.scrollLeft = 100; + const nonStickyLeftX = elements.container.offsetLeft + + elements.filler.clientWidth; + assert_equals(elements.sticky.offsetLeft, nonStickyLeftX); + // The inner sticky should not be offset from the outer. + assert_equals(elements.innerSticky.offsetLeft, 0); +}, 'before reaching the sticking point, neither sticky box should be offset'); + +test(() => { + const elements = setupNestedStickyTest('left', 50, 60); + elements.scroller.scrollLeft = 145; + const nonStickyLeftX = elements.container.offsetLeft + + elements.filler.clientWidth; + assert_equals(elements.sticky.offsetLeft, nonStickyLeftX); + assert_equals(elements.innerSticky.offsetLeft, 5); +}, 'the inner sticky can stick before the outer one if necessary'); + +test(() => { + const elements = setupNestedStickyTest('left', 50, 60); + elements.scroller.scrollLeft = 200; + + // This math cancels to sticky.offsetLeft == (scroller.scrollLeft + 50), but + // for clarity the calculations are left explicit. + const nonStickyLeftX = elements.container.offsetLeft + + elements.filler.clientWidth; + const targetLeftX = elements.scroller.scrollLeft + 50; + const stickyOffset = targetLeftX - nonStickyLeftX; + assert_equals(elements.sticky.offsetLeft, nonStickyLeftX + stickyOffset); + + // The inner sticky has similar math, but its offsetLeft is relative to the + // sticky element and in this test is the difference between the left values. + assert_equals(elements.innerSticky.offsetLeft, 10); +}, 'both sticky boxes can be stuck at the same time'); + +test(() => { + const elements = setupNestedStickyTest('left', 50, 60); + elements.scroller.scrollLeft = 300; + const maxOffsetInContainer = elements.container.offsetLeft + + elements.container.clientWidth - elements.sticky.clientWidth; + assert_equals(elements.sticky.offsetLeft, maxOffsetInContainer); + const maxOffsetInOuterSticky = elements.sticky.clientWidth - + elements.innerSticky.clientWidth; + assert_equals(elements.innerSticky.offsetLeft, maxOffsetInOuterSticky); +}, 'neither sticky can escape their containing block'); + +test(() => { + const elements = setupNestedStickyTest('left', 50, 300); + elements.scroller.scrollLeft = 100; + // The outer sticky has not stuck yet. + const nonStickyLeftX = elements.container.offsetLeft + + elements.filler.clientWidth; + assert_equals(elements.sticky.offsetLeft, nonStickyLeftX); + // But the inner sticky still cannot escape the outer sticky (as it is the + // containing block). + const maxOffsetInOuterSticky = elements.sticky.clientWidth - + elements.innerSticky.clientWidth; + assert_equals(elements.innerSticky.offsetLeft, maxOffsetInOuterSticky); +}, 'the inner sticky cannot be pushed outside the outer sticky'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-right.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-right.html new file mode 100644 index 0000000000..0f7e43f35a --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-right.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<title>Nested right-constrained position:sticky elements should render correctly</title> + +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that nested position:sticky elements with a right constraint render correctly" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body></body> + +<script> +test(() => { + const elements = setupNestedStickyTest('right', 25, 35); + elements.scroller.scrollLeft = 200; + const nonStickyLeftX = elements.container.offsetLeft + + elements.filler.clientWidth; + assert_equals(elements.sticky.offsetLeft, nonStickyLeftX); + // The inner sticky should not be offset from the outer. + const nonStickyInnerLeftX = elements.sticky.clientWidth - + elements.innerSticky.clientWidth; + assert_equals(elements.innerSticky.offsetLeft, nonStickyInnerLeftX); +}, 'before reaching the sticking point, neither sticky box should be offset'); + +test(() => { + const elements = setupNestedStickyTest('right', 25, 50); + elements.scroller.scrollLeft = 150; + const nonStickyLeftX = elements.container.offsetLeft + + elements.filler.clientWidth; + assert_equals(elements.sticky.offsetLeft, nonStickyLeftX); + assert_equals(elements.innerSticky.offsetLeft, 50); +}, 'the inner sticky can stick before the outer one if necessary'); + +test(() => { + const elements = setupNestedStickyTest('right', 25, 35); + elements.scroller.scrollLeft = 100; + + const nonStickyLeftX = elements.container.offsetLeft + + elements.filler.clientWidth; + const nonStickyBottomX = nonStickyLeftX + elements.sticky.clientWidth; + const targetBottomX = elements.scroller.clientWidth + + elements.scroller.scrollLeft - 25; + const stickyOffset = nonStickyBottomX - targetBottomX; + assert_equals(elements.sticky.offsetLeft, nonStickyLeftX - stickyOffset); + + // The inner sticky has similar math, but its offsetLeft is relative to the + // sticky element and in this test is (height - the difference between the + // top values). + assert_equals(elements.innerSticky.offsetLeft, 40); +}, 'both sticky boxes can be stuck at the same time'); + +test(() => { + const elements = setupNestedStickyTest('right', 25, 100); + elements.scroller.scrollLeft = 0; + assert_equals(elements.sticky.offsetLeft, elements.container.offsetLeft); + assert_equals(elements.innerSticky.offsetLeft, 0); +}, 'neither sticky can escape their containing block'); + +test(() => { + const elements = setupNestedStickyTest('right', 25, 500); + elements.scroller.scrollLeft = 200; + // It doesn't matter how big the inner sticky offset is, it cannot escape its + // containing block (the outer sticky). + assert_equals(elements.innerSticky.offsetLeft, 0); +}, 'the inner sticky cannot be pushed outside the outer sticky'); + +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-table-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-table-ref.html new file mode 100644 index 0000000000..36fabc3845 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-table-ref.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<title>Reference for nested position:sticky table elements should render correctly</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 250px; +} + +.scroller { + position: relative; + width: 100px; + height: 200px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 700px; +} + +.indicator { + position: absolute; + left: 0; + background-color: green; + height: 50px; + width: 50px; +} + +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div>You should see three green rectangles below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="contents"> + <div class="indicator" style="top: 100px;"></div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="contents"> + <div class="indicator" style="top: 150px;"></div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="contents"> + <div class="indicator" style="top: 250px;"></div> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-table.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-table.html new file mode 100644 index 0000000000..b2a8bf1e87 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-table.html @@ -0,0 +1,133 @@ +<!DOCTYPE html> +<title>Nested position:sticky table elements should render correctly</title> +<link rel="match" href="position-sticky-nested-table-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that nested position:sticky table elements render correctly" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 250px; +} + +.scroller { + position: relative; + width: 100px; + height: 200px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 700px; +} + +.prepadding { + height: 100px; +} + +table { + border-collapse: collapse; +} + +td, th { + height: 50px; + width: 50px; + padding: 0; +} + +th { + background: green; +} + +.sticky { + position: sticky; + top: 25px; +} + +.indicator { + position: absolute; + left: 0; + background-color: red; + height: 50px; + width: 50px; +} + +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div>You should see three green rectangles below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="contents"> + <div class="indicator" style="top: 100px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr class="sticky"> + <th class="sticky"></th> + </tr> + </thead> + <tbody> + <tr><td></td></tr> + <tr><td></td></tr> + <tr><td></td></tr> + </tbody> + </table> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="contents"> + <div class="indicator" style="top: 150px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr class="sticky"> + <th class="sticky"></th> + </tr> + </thead> + <tbody> + <tr><td></td></tr> + <tr><td></td></tr> + <tr><td></td></tr> + </tbody> + </table> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="contents"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr class="sticky"> + <th class="sticky"></th> + </tr> + </thead> + <tbody> + <tr><td></td></tr> + <tr><td></td></tr> + <tr><td></td></tr> + </tbody> + </table> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-thead-th.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-thead-th.html new file mode 100644 index 0000000000..51f58b7591 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-thead-th.html @@ -0,0 +1,133 @@ +<!DOCTYPE html> +<title>Nested position:sticky table elements should render correctly</title> +<link rel="match" href="position-sticky-nested-table-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that nested position:sticky table elements render correctly" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 250px; +} + +.scroller { + position: relative; + width: 100px; + height: 200px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 700px; +} + +.prepadding { + height: 100px; +} + +table { + border-collapse: collapse; +} + +td, th { + height: 50px; + width: 50px; + padding: 0; +} + +th { + background: green; +} + +.sticky { + position: sticky; + top: 25px; +} + +.indicator { + position: absolute; + left: 0; + background-color: red; + height: 50px; + width: 50px; +} + +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div>You should see three green rectangles below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="contents"> + <div class="indicator" style="top: 100px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr> + <th class="sticky"></th> + </tr> + </thead> + <tbody> + <tr><td></td></tr> + <tr><td></td></tr> + <tr><td></td></tr> + </tbody> + </table> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="contents"> + <div class="indicator" style="top: 150px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr> + <th class="sticky"></th> + </tr> + </thead> + <tbody> + <tr><td></td></tr> + <tr><td></td></tr> + <tr><td></td></tr> + </tbody> + </table> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="contents"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr> + <th class="sticky"></th> + </tr> + </thead> + <tbody> + <tr><td></td></tr> + <tr><td></td></tr> + <tr><td></td></tr> + </tbody> + </table> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-top.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-top.html new file mode 100644 index 0000000000..90dc52dba8 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-nested-top.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<title>Nested top-constrainted position:sticky elements should render correctly</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that nested position:sticky elements with a top constraint render correctly" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body></body> + +<script> +test(() => { + const elements = setupNestedStickyTest('top', 50, 60); + elements.scroller.scrollTop = 100; + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + assert_equals(elements.sticky.offsetTop, nonStickyTopY); + // The inner sticky should not be offset from the outer. + assert_equals(elements.innerSticky.offsetTop, 0); +}, 'before reaching the sticking point, neither sticky box should be offset'); + +test(() => { + const elements = setupNestedStickyTest('top', 50, 60); + elements.scroller.scrollTop = 145; + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + assert_equals(elements.sticky.offsetTop, nonStickyTopY); + assert_equals(elements.innerSticky.offsetTop, 5); +}, 'the inner sticky can stick before the outer one if necessary'); + +test(() => { + const elements = setupNestedStickyTest('top', 50, 60); + elements.scroller.scrollTop = 200; + + // This math cancels to sticky.offsetTop == (scroller.scrollTop + 50), but + // for clarity the calculations are left explicit. + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + const targetTopY = elements.scroller.scrollTop + 50; + const stickyOffset = targetTopY - nonStickyTopY; + assert_equals(elements.sticky.offsetTop, nonStickyTopY + stickyOffset); + + // The inner sticky has similar math, but its offsetTop is relative to the + // sticky element and in this test is the difference between the top values. + assert_equals(elements.innerSticky.offsetTop, 10); +}, 'both sticky boxes can be stuck at the same time'); + +test(() => { + const elements = setupNestedStickyTest('top', 50, 60); + elements.scroller.scrollTop = 300; + const maxOffsetInContainer = elements.container.offsetTop + + elements.container.clientHeight - elements.sticky.clientHeight; + assert_equals(elements.sticky.offsetTop, maxOffsetInContainer); + const maxOffsetInOuterSticky = elements.sticky.clientHeight - + elements.innerSticky.clientHeight; + assert_equals(elements.innerSticky.offsetTop, maxOffsetInOuterSticky); +}, 'neither sticky can escape their containing block'); + +test(() => { + const elements = setupNestedStickyTest('top', 50, 300); + elements.scroller.scrollTop = 100; + // The outer sticky has not stuck yet. + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + assert_equals(elements.sticky.offsetTop, nonStickyTopY); + // But the inner sticky still cannot escape the outer sticky (as it is the + // containing block). + const maxOffsetInOuterSticky = elements.sticky.clientHeight - + elements.innerSticky.clientHeight; + assert_equals(elements.innerSticky.offsetTop, maxOffsetInOuterSticky); +}, 'the inner sticky cannot be pushed outside the outer sticky'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-offset-overflow.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-offset-overflow.html new file mode 100644 index 0000000000..4882e110eb --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-offset-overflow.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<title>Sticky positioning can cause overflow but must be accessible.</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that a sticky positioned element +does not extend overflow" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +.container { + overflow-y: scroll; + width: 100px; + height: 100px; +} + +.box { + background-color: green; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + top: 200px; /* Forces the sticky position element below the overflow. */ +} +</style> + +<div id="scroller1" class="container"> + <div class="sticky box"></div> +</div> + +<script> +test(() => { + var scroller = document.getElementById('scroller1'); + var sticky = scroller.querySelector('.sticky'); + + var stickyOffset = sticky.offsetTop - + scroller.scrollTop - scroller.offsetTop; + assert_equals(stickyOffset, 50); + assert_equals(scroller.scrollHeight, 100); +}, 'sticky position offset should be contained by scrolling box'); + +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-offset-top-left.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-offset-top-left.html new file mode 100644 index 0000000000..ade9e108cf --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-offset-top-left.html @@ -0,0 +1,78 @@ +<!DOCTYPE html> +<title>Sticky positioned element should be observable by offsetTop and offsetLeft</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that a sticky positioned element +should be observable by offsetTop/offsetLeft." /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +body { + margin: 0; +} + +.container { + position: relative; /* Required for offsetTop/offsetLeft tests. */ + overflow: scroll; + width: 200px; + height: 200px; +} + +.spacer { + width: 2000px; + height: 2000px; +} + +.box { + width: 100px; + height: 100px; + background-color: green; +} + +.sticky { + position: sticky; + top: 50px; + left: 20px; +} +</style> + +<div id="scroller1" class="container"> + <div class="spacer"></div> +</div> + +<script> +test(() => { + var scroller = document.getElementById('scroller1'); + scroller.scrollTop = 100; + scroller.scrollLeft = 75; + + var sticky = document.createElement('div'); + sticky.className = 'sticky box'; + scroller.insertBefore(sticky, scroller.querySelector('.spacer')); + + assert_equals(sticky.offsetTop, scroller.scrollTop + 50); + assert_equals(sticky.offsetLeft, scroller.scrollLeft + 20); +}, 'offsetTop/offsetLeft should be correct for sticky after script insertion'); +</script> + +<div id="scroller2" class="container"> + <div id="sticky2" class="sticky box"></div> + <div class="spacer"></div> +</div> + +<script> +test(function() { + var scroller = document.getElementById('scroller2'); + var sticky = document.getElementById('sticky2'); + scroller.scrollTop = 100; + scroller.scrollLeft = 75; + + var div = document.createElement('div'); + div.style.height = '65px'; + scroller.insertBefore(div, sticky); + + assert_equals(sticky.offsetTop, scroller.scrollTop + 50); + assert_equals(sticky.offsetLeft, scroller.scrollLeft + 20); +}, 'offsetTop/offsetLeft should be correct for sticky after script-caused layout'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-clip-container-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-clip-container-ref.html new file mode 100644 index 0000000000..2a29b435a7 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-clip-container-ref.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> +<title>Sticky elements should not consider overflow: clip containers as possible scroll ancestor</title> +<style> +body { + margin: 0; + overflow: hidden; /* hide scrollbars */ +} + +#container { + height: 300px; + overflow-y: scroll; +} + +#overflowClipContainer { + overflow: visible; + height: 600px; +} + +#sticky { + position: sticky; + top: 0; + height: 50px; + background-color: yellow; +} +</style> +<script> +function doTest() +{ + container.scrollTo(0, 50); +} +window.addEventListener('load', doTest, false); +</script> +<div id="container"> + <div id="overflowClipContainer"> + <div id="sticky"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-clip-container.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-clip-container.html new file mode 100644 index 0000000000..63356349af --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-clip-container.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html> +<title>Sticky elements should not consider overflow: clip containers as possible scroll ancestor</title> +<link rel="match" href="position-sticky-overflow-clip-container-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that sticky elements do not consider overflow:clip containers as possible scroll ancestor"/> +<style> +body { + margin: 0; + overflow: hidden; /* hide scrollbars */ +} + +#container { + height: 300px; + overflow: auto; +} + +#overflowClipContainer { + overflow: clip; + height: 600px; +} + +#sticky { + position: sticky; + top: 0; + height: 50px; + background-color: yellow; +} +</style> +<script> +function doTest() +{ + container.scrollTo(0, 50); +} +window.addEventListener('load', doTest, false); +</script> +<div id="container"> + <div id="overflowClipContainer"> + <div id="sticky"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-hidden.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-hidden.html new file mode 100644 index 0000000000..622ca8fbef --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-hidden.html @@ -0,0 +1,86 @@ +<!DOCTYPE html> +<title>position:sticky elements should respect an overflow:hidden ancestor</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements adhere to an overflow:hidden ancestor" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body></body> + +<script> +test(() => { + const outer_scroller = document.createElement('div'); + outer_scroller.style.width = '100px'; + outer_scroller.style.height = '100px'; + outer_scroller.style.overflow = 'scroll'; + + const inner_scroller = document.createElement('div'); + inner_scroller.style.width = '80%'; + inner_scroller.style.height = '200px'; + inner_scroller.style.overflow = 'hidden'; + + const sticky = document.createElement('div'); + sticky.style.width = '20px'; + sticky.style.height = '20px'; + sticky.style.position = 'sticky'; + sticky.style.top = '0'; + sticky.style.background = 'red'; + + const spacer = document.createElement('div'); + spacer.style.height = '500px'; + + inner_scroller.appendChild(sticky); + inner_scroller.appendChild(spacer); + outer_scroller.appendChild(inner_scroller); + document.body.appendChild(outer_scroller); + + outer_scroller.scrollTop = 50; + + // The sticky should attach to the inner scroller, and so should not stick. + assert_equals(sticky.offsetTop, inner_scroller.offsetTop); +}, 'A sticky element should attach to an overflow:hidden ancestor'); + +// This tests a specific bug in Firefox where the sticky element incorrectly +// started sticking when inside a table. See https://bugzilla.mozilla.org/show_bug.cgi?id=1488810 +test(() => { + const outer_scroller = document.createElement('div'); + outer_scroller.style.width = '100px'; + outer_scroller.style.height = '100px'; + outer_scroller.style.overflow = 'scroll'; + + const table = document.createElement('div'); + table.style.display = 'table'; + + const tr = document.createElement('div'); + tr.style.display = 'table-row'; + + const inner_scroller = document.createElement('div'); + inner_scroller.style.display = 'table-cell'; + inner_scroller.style.overflow = 'hidden'; + + const sticky = document.createElement('div'); + sticky.style.width = '20px'; + sticky.style.height = '20px'; + sticky.style.position = 'sticky'; + sticky.style.top = '0'; + sticky.style.background = 'red'; + + const spacer = document.createElement('div'); + spacer.style.height = '500px'; + + inner_scroller.appendChild(sticky); + inner_scroller.appendChild(spacer); + tr.append(inner_scroller); + table.appendChild(tr); + outer_scroller.appendChild(table); + document.body.appendChild(outer_scroller); + + outer_scroller.scrollTop = 50; + + // The sticky should attach to the inner scroller, and so should not stick. + assert_equals(sticky.offsetTop, inner_scroller.offsetTop); +}, 'A sticky element should attach to an overflow:hidden ancestor inside a table'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-padding.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-padding.html new file mode 100644 index 0000000000..71b74e7886 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-overflow-padding.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<title>position:sticky elements should respect padding on their ancestor overflow element</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements respect padding on their ancestor overflow element" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body></body> + +<script> +test(() => { + const elements = setupStickyTest('top', 50); + elements.scroller.style.padding = '20px 0'; + + // Before sticking; the element isn't within the padding range. + elements.scroller.scrollTop = 150; + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + assert_equals(elements.sticky.offsetTop, nonStickyTopY); +}, 'A sticky element should not be affected by ancestor padding until it ' + + 'reaches it'); + +test(() => { + const elements = setupStickyTest('top', 50); + elements.sticky.style.top = '0'; + elements.scroller.style.padding = '20px 0'; + + elements.scroller.scrollTop = 200; + + // This math cancels to sticky.offsetTop == (scroller.scrollTop + 50), but + // for clarity the calculations are left explicit. + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + const targetTopY = elements.scroller.scrollTop; + const stickyOffset = targetTopY - nonStickyTopY; + + assert_equals(elements.sticky.offsetTop, nonStickyTopY + stickyOffset + 20); +}, 'A sticky element should be offset by ancestor padding even when stuck'); + +test(() => { + const elements = setupStickyTest('top', 50); + elements.sticky.style.top = '0'; + elements.scroller.style.padding = '20px 0'; + + elements.scroller.scrollTop = 315; + const maxOffsetInContainer = elements.container.offsetTop + + elements.container.clientHeight - elements.sticky.clientHeight; + assert_equals(elements.sticky.offsetTop, maxOffsetInContainer); +}, 'Ancestor overflow padding does not allow a sticky element to escape its ' + + 'container'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-parsing.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-parsing.html new file mode 100644 index 0000000000..b147429e69 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-parsing.html @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<title>Position value 'sticky' should be a valid value</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#position-property" /> +<meta name="assert" content="This test checks that setting position to 'sticky' +should be allowed." /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<!-- We need something to create elements in. --> +<body></body> + +<script> +const displayTypes = [ + 'block', + 'inline', + 'run-in', + 'flow', + 'flow-root', + 'table', + 'flex', + 'grid', + 'ruby', + 'subgrid', + 'list-item', + 'table-row-group', + 'table-header-group', + 'table-footer-group', + 'table-row', + 'table-cell', + 'table-caption', + // Sticky does not apply to table-column or table-column-group, but the + // computed value should still be sticky. + 'table-column', + 'table-column-group', + 'ruby-base', + 'ruby-text', + 'ruby-base-container', + 'ruby-text-container', + 'contents', + 'none', +]; + +test(() => { + for (displayValue of displayTypes) { + let div = document.createElement('div'); + let style = `position: sticky; display: ${displayValue};`; + div.setAttribute('style', style); + document.body.appendChild(div); + + // We only check display values that the browser under test recognizes. + if (div.style.display == displayValue) { + assert_equals(getComputedStyle(div).position, 'sticky', + `Expected sticky to be valid for display: ${displayValue}`); + } + document.body.removeChild(div); + } +}, 'The value of sticky for the position property should be parsed correctly'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-rendering-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-rendering-ref.html new file mode 100644 index 0000000000..b4411c3bed --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-rendering-ref.html @@ -0,0 +1,104 @@ +<!DOCTYPE html> +<title>Reference for position:sticky elements should be rendered at their sticky offset</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 250px; +} + +.inlineGroup { + display: inline-block; + position: relative; + width: 250px; + height: 150px; +} + +.scroller { + position: relative; + width: 100px; + height: 200px; + overflow-x: hidden; + overflow-y: auto; +} + +.inlineGroup .scroller { + position: relative; + width: 200px; + height: 100px; + overflow-x: auto; + overflow-y: hidden; +} + +.contents { + height: 500px; +} + +.inlineGroup .contents { + height: 100%; + width: 500px; +} + +.indicator { + background-color: green; + position: absolute; +} + +.box { + width: 100%; + height: 100px; +} + +.inlineGroup .box { + height: 100%; + width: 100px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 125; + document.getElementById('scroller2').scrollTop = 50; + document.getElementById('scroller3').scrollLeft = 125; + document.getElementById('scroller4').scrollLeft = 75; +}); +</script> + +<div>You should see four green squares below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="contents"> + <div class="indicator box" style="top: 175px;"></div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="contents"> + <div class="indicator box" style="top: 125px;"></div> + </div> + </div> +</div> + +<!-- Force break to make sure we are within 800px wide. --> +<div></div> + +<div class="inlineGroup"> + <div id="scroller3" class="scroller"> + <div class="contents"> + <div class="indicator box" style="left: 175px;"></div> + </div> + </div> +</div> + +<div class="inlineGroup"> + <div id="scroller4" class="scroller"> + <div class="contents"> + <div class="indicator box" style="left: 150px;"></div> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-rendering.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-rendering.html new file mode 100644 index 0000000000..a4e03c59d8 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-rendering.html @@ -0,0 +1,159 @@ +<!DOCTYPE html> +<title>position:sticky elements should be rendered at their sticky offset</title> +<link rel="match" href="position-sticky-rendering-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements are rendered correctly" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 250px; +} + +.inlineGroup { + display: inline-block; + position: relative; + width: 250px; + height: 150px; +} + +.scroller { + position: relative; + width: 100px; + height: 200px; + overflow-x: hidden; + overflow-y: auto; +} + +.inlineGroup .scroller { + position: relative; + width: 200px; + height: 100px; + overflow-x: auto; + overflow-y: hidden; +} + +.contents { + height: 500px; +} + +.inlineGroup .contents { + height: 100%; + width: 500px; +} + +.prepadding { + height: 100px; +} + +.inlineGroup .prepadding { + display: inline-block; + height: 100%; + width: 100px; +} + +.container { + height: 200px; +} + +.inlineGroup .container { + display: inline-block; + height: 100%; + width: 200px; +} + +.filler { + height: 100px; +} + +.inlineGroup .filler { + display: inline-block; + height: 100%; + width: 100px; +} + +.indicator { + background-color: red; + position: absolute; +} + +.sticky { + background-color: green; + position: sticky; +} + +.box { + width: 100%; + height: 100px; +} + +.inlineGroup .box { + display: inline-block; + height: 100%; + width: 100px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 125; + document.getElementById('scroller2').scrollTop = 50; + document.getElementById('scroller3').scrollLeft = 125; + document.getElementById('scroller4').scrollLeft = 75; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see four green squares below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator box" style="top: 175px;"></div> + <div class="contents"> + <div class="prepadding"></div> + <div class="container"> + <div style="top: 50px;" class="sticky box"></div> + </div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator box" style="top: 125px;"></div> + <div class="contents"> + <div class="prepadding"></div> + <div class="container"> + <div class="filler"></div> + <div style="bottom: 25px;" class="sticky box"></div> + </div> + </div> + </div> +</div> + +<!-- Force break to make sure we are within 800px wide. --> +<div></div> + +<div class="inlineGroup"> + <div id="scroller3" class="scroller"> + <div class="indicator box" style="left: 175px;"></div> + <div class="contents"> + <!-- As these elements are inline, they are whitespace sensitive. --> + <div class="prepadding"></div><div class="container"><div style="left: 50px;" class="sticky box"></div></div> + </div> + </div> +</div> + +<div class="inlineGroup"> + <div id="scroller4" class="scroller"> + <div class="indicator box" style="left: 150px;"></div> + <div class="contents"> + <!-- As these elements are inline, they are whitespace sensitive. --> + <div class="prepadding"></div><div class="container"><div class="filler"></div><div style="right: 25px;" class="sticky box"></div></div> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-right-002.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-right-002.html new file mode 100644 index 0000000000..e83189a498 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-right-002.html @@ -0,0 +1,96 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Position Test: sticky element with right offset specified with px unit</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + <link rel="match" href="reference/position-sticky-right-002-ref.html"> + + <meta name="flags" content=""> + + <style> + div.scrolling-container + { + background-image: url("support/100x100-red.png"); + background-repeat: no-repeat; + height: 150px; + margin-bottom: 30px; + overflow-y: hidden; + position: static; + white-space: nowrap; + width: 250px; + } + + div#first-scrolling-container + { + background-position: 75px top; + } + + div#second-scrolling-container + { + background-position: 50px top; + } + + div#third-scrolling-container + { + background-position: left top; + } + + div.horizontal-spacer + { + display: inline-block; + height: 100%; + width: 100px; + } + + div.content + { + display: inline-block; + height: 100%; + width: 300px; + } + + div.sticky + { + background-color: green; + display: inline-block; + height: 100px; + position: sticky; + right: 100px; + vertical-align: top; + width: 100px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollLeft = 25; document.getElementById("second-scrolling-container").scrollLeft = 100; document.getElementById("third-scrolling-container").scrollLeft = 200;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <!-- + first-scrolling-container: before reaching the sticking point + --> + + <div id="first-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="first-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> + + <!-- + second-scrolling-container: when reaching the sticking point and beyond + --> + + <div id="second-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="second-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> + + + <div id="third-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="third-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-right-003.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-right-003.html new file mode 100644 index 0000000000..ea712a99da --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-right-003.html @@ -0,0 +1,96 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Position Test: sticky element with right offset specified with percentage unit</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + <link rel="match" href="reference/position-sticky-right-002-ref.html"> + + <meta name="flags" content=""> + + <style> + div.scrolling-container + { + background-image: url("support/100x100-red.png"); + background-repeat: no-repeat; + height: 150px; + margin-bottom: 30px; + overflow-y: hidden; + position: static; + white-space: nowrap; + width: 250px; + } + + div#first-scrolling-container + { + background-position: 75px top; + } + + div#second-scrolling-container + { + background-position: 50px top; + } + + div#third-scrolling-container + { + background-position: left top; + } + + div.horizontal-spacer + { + display: inline-block; + height: 100%; + width: 100px; + } + + div.content + { + display: inline-block; + height: 100%; + width: 300px; + } + + div.sticky + { + background-color: green; + display: inline-block; + height: 100px; + position: sticky; + right: 40%; + vertical-align: top; + width: 100px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollLeft = 25; document.getElementById("second-scrolling-container").scrollLeft = 100; document.getElementById("third-scrolling-container").scrollLeft = 200;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <!-- + first-scrolling-container: before reaching the sticking point + --> + + <div id="first-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="first-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> + + <!-- + second-scrolling-container: when reaching the sticking point and beyond + --> + + <div id="second-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="second-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> + + + <div id="third-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer"></div><div class="content"><div class="horizontal-spacer"></div><div id="third-sticky" class="sticky"></div><div class="horizontal-spacer"></div></div><div class="horizontal-spacer"></div> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-right.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-right.html new file mode 100644 index 0000000000..82d0e9af1d --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-right.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<title>position:sticky elements should respect the right constraint</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements obey their right anchor after scrolling" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body></body> + +<script> +test(() => { + const elements = setupStickyTest('right', 25); + elements.scroller.scrollLeft = 200; + const nonStickyLeftX = elements.container.offsetLeft + + elements.filler.clientWidth; + assert_equals(elements.sticky.offsetLeft, nonStickyLeftX); +}, 'before reaching the sticking point the sticky box should not be offset'); + +test(() => { + const elements = setupStickyTest('right', 25); + elements.scroller.scrollLeft = 75; + + const nonStickyLeftX = elements.container.offsetLeft + + elements.filler.clientWidth; + const nonStickyRightX = nonStickyLeftX + elements.sticky.clientWidth; + const targetRightX = elements.scroller.clientWidth + + elements.scroller.scrollLeft - 25; + const stickyOffset = nonStickyRightX - targetRightX; + + assert_equals(elements.sticky.offsetLeft, nonStickyLeftX - stickyOffset); +}, 'after reaching the sticking point the sticky box should be offset'); + +test(() => { + const elements = setupStickyTest('right', 25); + elements.scroller.scrollLeft = 15; + assert_equals(elements.sticky.offsetLeft, elements.container.offsetLeft); +}, 'the sticky box should not be pushed outside its containing block'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-root-scroller.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-root-scroller.html new file mode 100644 index 0000000000..596fd9b240 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-root-scroller.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<title>position:sticky should operate correctly for the root scroller</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements work when using the root (document) scroller" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +body { + /* Assumption: 3000px is taller than any user agents test window size. */ + height: 3000px; +} + +#sticky { + position: sticky; + top: 50px; + width: 200px; + height: 200px; + background-color: green; +} +</style> + +<div id="sticky"></div> + +<script> +test(() => { + window.scrollTo(0, 700); + assert_equals(sticky.offsetTop, 700 + 50); +}, 'Sticky elements work with the root (document) scroller'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-reposition-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-reposition-ref.html new file mode 100644 index 0000000000..487a2322fc --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-reposition-ref.html @@ -0,0 +1,10 @@ +<!doctype html> +<title>Test that style mutation of contain:strict plus position:sticky updates sticky position</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> +<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> +<div id="scroller" style="width: 200px; height: 200px; overflow-y: scroll; + will-change: transform;"> + <div id="scrollbar" style="width: 100px; height: 100px; position: sticky; background: lightblue; + top: 5px; left: 50px; contain: strict;"></div> + <div style="width: 100px; height: 500px;"></div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-reposition.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-reposition.html new file mode 100644 index 0000000000..b75275c64f --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-reposition.html @@ -0,0 +1,20 @@ +<!doctype html> +<html class="reftest-wait"> +<title>Test that style mutation of contain:strict plus position:sticky updates sticky position</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> +<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> +<link rel="match" href="position-sticky-scroll-reposition-ref.html"> +<div id="scroller" style="width: 200px; height: 200px; overflow-y: scroll; + will-change: transform;"> + <div id="sticky" style="width: 100px; height: 100px; position: sticky; background: lightblue; + top: 50px; left: 50px; contain: strict;"></div> + <div style="width: 100px; height: 500px;"></div> +</div> +<script src="/common/reftest-wait.js"></script> +<script> + requestAnimationFrame(() => + requestAnimationFrame(() => { + sticky.style.top = '5px'; + takeScreenshot(); + })); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-with-clip-and-abspos-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-with-clip-and-abspos-ref.html new file mode 100644 index 0000000000..d9fe863d80 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-with-clip-and-abspos-ref.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<meta charset="utf-8"> +<title>position:sticky should operate correctly</title> +<link rel="author" href="mailto:masonf@chromium.org"> + + + + +<div style="position: fixed;">There should be text visible below.</div> +<div style="height: 200px;width:600px;position: fixed;top: 0px;"> + <div style="position: relative;top: 100px;"> + <div style="height: 150px;width: 500px;position: absolute;backface-visibility: hidden;background: white;"> + </div> + <div style="overflow: hidden;"> + <a style="position: relative;">THIS SHOULD STAY VISIBLE<BR>IF YOU SCROLL DOWN</a> + </div> + </div> +</div> +<div style="height: 2200px;"> +</div> +<script> + window.onload = function() { + requestAnimationFrame(() => { + requestAnimationFrame(() => { + window.scrollTo(0,300); + document.documentElement.classList.remove("reftest-wait"); + }); + }); + }; +</script> +</html> + diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-with-clip-and-abspos.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-with-clip-and-abspos.html new file mode 100644 index 0000000000..fb7edfe498 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scroll-with-clip-and-abspos.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<meta charset="utf-8"> +<title>position:sticky should operate correctly</title> +<link rel="author" href="mailto:masonf@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the combination of position:sticky, overflow clip, and out-of-flow descendants are properly displayed when scrolled" /> +<link rel="match" href="position-sticky-scroll-with-clip-and-abspos-ref.html"> + +<div style="position: fixed;">There should be text visible below.</div> +<div style="height: 200px;width:600px;position: sticky;top: 0px;"> + <div style="position: relative;top: 100px;"> + <div style="height: 150px;width: 500px;position: absolute;backface-visibility: hidden;background: white;"> + </div> + <div style="overflow: hidden;"> + <a style="position: relative;">THIS SHOULD STAY VISIBLE<BR>IF YOU SCROLL DOWN</a> + </div> + </div> +</div> +<div style="height: 2000px;"> +</div> +<script> + window.onload = function() { + requestAnimationFrame(() => { + requestAnimationFrame(() => { + window.scrollTo(0,300); + document.documentElement.classList.remove("reftest-wait"); + }); + }); + }; +</script> +</html> + diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-scrollIntoView.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scrollIntoView.html new file mode 100644 index 0000000000..6fb4723529 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scrollIntoView.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<title>Scrolling to sticky position elements uses their unshifted position</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#stickypos-scroll" /> +<meta name="assert" content="This test checks that scrolling to sticky position elements uses their initial position" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> + +h1 { + position: sticky; + background: #ddd; + border: 1px solid black; + top: 0px; + bottom: 0px; +} + +section { + height: 100vh; +} +</style> + +<body> + <h1>Title 1</h1> + <section></section> + <h1>Title 2</h1> + <section></section> + <h1>Title 3</h1> + <section></section> + +<script> +test(() => { + window.scrollTo(0, 0); + const element = document.querySelectorAll('h1')[2]; + element.scrollIntoView(); + assert_approx_equals(document.scrollingElement.scrollTop, element.offsetTop, 1); +}, 'scrolling a sticky element into view should use its unshifted position'); +</script> +</body> + diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-scrolled-remove-sibling.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scrolled-remove-sibling.html new file mode 100644 index 0000000000..845454e1b3 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-scrolled-remove-sibling.html @@ -0,0 +1,99 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Positioned Layout Test: element with 'position: sticky' and removing a sibling in the vertical axis and in the horizontal axis</title> + + <link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + + <meta name="flags" content=""> + + <style> + div#scrollingContainerVert + { + background-color: red; + height: 100px; + overflow: auto; + width: 200px; + } + + div#scrollingContainerHoriz + { + background-color: red; + height: 100px; + overflow-x: auto; + overflow-y: hidden; + width: 200px; + } + + div#elemStickyVert + { + background-color: green; + height: 100px; + position: sticky; + top: 0px; + } + + div#scrollingContainerHoriz > div + { + display: inline-block; + height: 100%; + } + + div#elemStickyHoriz + { + background-color: green; + left: 0px; + position: sticky; + width: 200px; + } + + div#tallItem + { + height: 600px; + } + + div#wideItem + { + width: 600px; + } + </style> + + + <script src="/resources/testharness.js"></script> + + <script src="/resources/testharnessreport.js"></script> + + <p>Test passes if there is a filled green square and <strong>no scrollbar</strong>. + + <div id="scrollingContainerVert"> + + <div id="elemStickyVert"></div> + + <div id="tallItem"></div> + + </div> + + + <div id="scrollingContainerHoriz"> + + <div id="elemStickyHoriz"></div><div id="wideItem"></div> + + </div> + + + <script> + test(()=> { + scrollingContainerVert.scrollTop = 600; + tallItem.style.display = "none"; + assert_equals(scrollingContainerVert.scrollHeight, 100); + }, "Sticky position and its overflow contribution in the vertical axis"); + + test(()=> { + scrollingContainerHoriz.scrollLeft = 600; + wideItem.style.display = "none"; + assert_equals(scrollingContainerHoriz.scrollWidth, 200); + }, "Sticky position and its overflow contribution in the horizontal axis"); + </script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-stacking-context-002.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-stacking-context-002.html new file mode 100644 index 0000000000..1cc162880a --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-stacking-context-002.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Positioned Layout Test: an element with 'position: sticky' creates a stacking context</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + + <meta name="assert" content="This test checks that an element with 'position: sticky' creates a stacking context. In this test, the first 2 divs have the same 'auto' z-index value but since div#sticky is last in document tree order, then it must overlap div#overlapped-red. The final div#overlap-bottom-half-of-sticky exists to make sure that the div#sticky is squeezed, is 'sandwiched' between the other 2."> + + <style> + div + { + height: 100px; + width: 100px; + } + + div#overlapped-red + { + background-color: red; + position: absolute; + } + + div#sticky + { + background: linear-gradient(to bottom, green 51%, red 49%); + position: sticky; + } + + div#overlap-bottom-half-of-sticky + { + background-color: green; + bottom: 50px; + height: 50px; + position: relative; + } + </style> + + <p>Test passes if there is a filled green square and <strong>no red</strong>. + + <div id="overlapped-red"></div> + + <div id="sticky"></div> + + <div id="overlap-bottom-half-of-sticky"></div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-stacking-context-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-stacking-context-ref.html new file mode 100644 index 0000000000..2db17cc424 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-stacking-context-ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>Reference for position: sticky should create a stacking context</title> + +<style> +.indicator { + background-color: green; +} + +.box { + width: 200px; + height: 200px; +} +</style> + +<div>You should see a single green box below. No red or blue should be visible.</div> + +<div class="indicator box"></div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-stacking-context.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-stacking-context.html new file mode 100644 index 0000000000..4e91dfbd91 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-stacking-context.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<title>position: sticky should create a stacking context</title> +<link rel="match" href="position-sticky-stacking-context-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="position:sticky elements should create a stacking context" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +.indicator { + position: absolute; + background-color: green; + z-index: 1; +} + +.sticky { + position: sticky; + z-index: 0; +} + +.child { + position: relative; + background-color: red; + z-index: 2; +} + +.box { + width: 200px; + height: 200px; +} +</style> + +<script> +window.addEventListener('load', function() { + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}) +</script> + +<div>You should see a single green box below. No red or blue should be visible.</div> + +<div class="indicator box"></div> +<div class="sticky box"> + <!-- Because sticky forms a stacking context, this child remains on bottom + even though it has a higher z-index than the indicator box. --> + <div class="child box"></div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-parts-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-parts-ref.html new file mode 100644 index 0000000000..9ba42e18b2 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-parts-ref.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<title>Nested position:sticky table elements should render correctly</title> +<style> +.scroller { + width: 100px; + height: 250px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 700px; +} + +table { + border-collapse: collapse; +} + +#child, td, th { + height: 50px; + width: 50px; + padding: 0; + background: green; +} + +.prepadding { + height: 155px; +} + +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 150; +}); +</script> + +<div>There should be a green square at the top of the scroll view and no red or blue visible.</div> + + <div id="scroller1" class="scroller"> + <div class="contents"> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div id="child"></div></td></tr> + </tbody> + </table> + </div> + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-parts.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-parts.html new file mode 100644 index 0000000000..eb32099d44 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-parts.html @@ -0,0 +1,76 @@ +<!DOCTYPE html> +<title>Nested position:sticky table elements should render correctly</title> +<link rel="match" href="position-sticky-table-parts-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that nested position:sticky table elements render correctly" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +.scroller { + position: relative; + width: 100px; + height: 250px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 700px; +} + +table { + border-collapse: collapse; +} + +.child, td, th { + height: 50px; + width: 50px; + padding: 0; +} + +.child { + background: green; +} + +table * { + position: sticky; + top: 5px; +} + +.indicator { + position: absolute; + left: 0; + background-color: red; + height: 50px; + width: 50px; +} + +</style> + +<script> +window.addEventListener('load', function() { + document.body.offsetTop; + document.getElementById('scroller1').scrollTop = 150; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>There should be a green square at the top of the scroll view and no red or blue visible.</div> + +<div id="scroller1" class="scroller"> + <div class="contents"> + <div class="indicator" style="top: 155px;"></div> + <table> + <tbody> + <tr><td><div class="child"></div></td></tr> + <tr><td></td></tr> + <tr><td></td></tr> + <tr><td></td></tr> + <tr><td></td></tr> + <tr><td></td></tr> + <tr><td></td></tr> + </tbody> + </table> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-bottom-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-bottom-ref.html new file mode 100644 index 0000000000..e851315641 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-bottom-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky bottom constraint should behave correctly for <td> elements</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 550px; +} + +.indicator { + position: absolute; + background-color: green; + left: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 0; + document.getElementById('scroller2').scrollTop = 75; + document.getElementById('scroller3').scrollTop = 150; +}); +</script> + +<div>You should see three green boxes below. No red should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 200px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-bottom.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-bottom.html new file mode 100644 index 0000000000..7cd3b8d695 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-bottom.html @@ -0,0 +1,109 @@ +<!DOCTYPE html> +<title>position:sticky bottom constraint should behave correctly for <td> elements</title> +<link rel="match" href="position-sticky-table-td-bottom-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky bottom constraint behaves correctly for <td> elements" /> + +<style> +table { + border-collapse:collapse; +} + +td { + padding: 0; +} + +td > div { + height: 50px; + width: 50px; +} + +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.prepadding { + height: 100px; +} + +.postpadding { + height: 250px; +} + +.indicator { + position: absolute; + background-color: red; + left: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + bottom: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 0; + document.getElementById('scroller2').scrollTop = 75; + document.getElementById('scroller3').scrollTop = 150; +}); +</script> + +<div>You should see three green boxes below. No red should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="prepadding"></div> + <table> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td class="sticky"><div></div></td></td> + <tr><td><div></div></td></tr> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="prepadding"></div> + <table> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td class="sticky"><div></div></td></td> + <tr><td><div></div></td></tr> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 200px;"></div> + <div class="prepadding"></div> + <table> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td class="sticky"><div></div></td></td> + <tr><td><div></div></td></tr> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-left-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-left-ref.html new file mode 100644 index 0000000000..40f80128d1 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-left-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky left constraint should behave correctly for <td> elements</title> + +<style> +.group { + position: relative; + width: 250px; + height: 150px; +} + +.scroller { + position: relative; + width: 200px; + height: 100px; + overflow-x: auto; + overflow-y: hidden; +} + +.contents { + height: 10px; + width: 500px; +} + +.indicator { + position: absolute; + background-color: green; + top: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 50; + document.getElementById('scroller2').scrollLeft = 175; + document.getElementById('scroller3').scrollLeft = 250; +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="left: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="left: 200px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="left: 250px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-left.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-left.html new file mode 100644 index 0000000000..34d31f3eb1 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-left.html @@ -0,0 +1,118 @@ +<!DOCTYPE html> +<title>position:sticky left constraint should behave correctly for <td> elements</title> +<link rel="match" href="position-sticky-table-td-left-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky left constraint behaves correctly for <td> elements" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +table { + border-collapse: collapse; + margin-left: 100px; +} + +td { + padding: 0; +} + +td > div { + height: 50px; + width: 50px; +} + +.group { + position: relative; + width: 250px; + height: 150px; +} + +.scroller { + position: relative; + width: 200px; + height: 100px; + overflow-x: auto; + overflow-y: hidden; +} + +.postpadding { + height: 10px; + width: 500px; +} + +.indicator { + position: absolute; + background-color: red; + top: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + left: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 50; + document.getElementById('scroller2').scrollLeft = 175; + document.getElementById('scroller3').scrollLeft = 250; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="left: 150px;"></div> + <table> + <tbody> + <tr> + <td><div></div></td> + <td class="sticky"><div></div></td> + <td><div></div></td> + <td><div></div></td> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="left: 200px;"></div> + <table> + <tbody> + <tr> + <td><div></div></td> + <td class="sticky"><div></div></td> + <td><div></div></td> + <td><div></div></td> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="left: 250px;"></div> + <table> + <tbody> + <tr> + <td><div></div></td> + <td class="sticky"><div></div></td> + <td><div></div></td> + <td><div></div></td> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-right-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-right-ref.html new file mode 100644 index 0000000000..633c2fa50e --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-right-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky right constraint should behave correctly for <td> elements</title> + +<style> +.group { + position: relative; + width: 250px; + height: 150px; +} + +.scroller { + position: relative; + width: 200px; + height: 100px; + overflow-x: auto; + overflow-y: hidden; +} + +.contents { + height: 10px; + width: 500px; +} + +.indicator { + position: absolute; + background-color: green; + top: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 0; + document.getElementById('scroller2').scrollLeft = 75; + document.getElementById('scroller3').scrollLeft = 150; +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="left: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="left: 200px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="left: 250px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-right.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-right.html new file mode 100644 index 0000000000..093af91a55 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-right.html @@ -0,0 +1,118 @@ +<!DOCTYPE html> +<title>position:sticky right constraint should behave correctly for <td> elements</title> +<link rel="match" href="position-sticky-table-td-right-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky right constraint behaves correctly for <td> elements" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +table { + border-collapse: collapse; + margin-left: 150px; +} + +td { + padding: 0; +} + +td > div { + height: 50px; + width: 50px; +} + +.group { + position: relative; + width: 250px; + height: 150px; +} + +.scroller { + position: relative; + width: 200px; + height: 100px; + overflow-x: auto; + overflow-y: hidden; +} + +.postpadding { + height: 10px; + width: 500px; +} + +.indicator { + position: absolute; + background-color: red; + top: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + right: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 0; + document.getElementById('scroller2').scrollLeft = 75; + document.getElementById('scroller3').scrollLeft = 150; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="left: 150px;"></div> + <table> + <tbody> + <tr> + <td><div></div></td> + <td><div></div></td> + <td class="sticky"><div></div></td> + <td><div></div></td> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="left: 200px;"></div> + <table> + <tbody> + <tr> + <td><div></div></td> + <td><div></div></td> + <td class="sticky"><div></div></td> + <td><div></div></td> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="left: 250px;"></div> + <table> + <tbody> + <tr> + <td><div></div></td> + <td><div></div></td> + <td class="sticky"><div></div></td> + <td><div></div></td> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-top-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-top-ref.html new file mode 100644 index 0000000000..2ef7c2678b --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-top-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky top constraint should behave correctly for <td> elements</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 550px; +} + +.indicator { + position: absolute; + background-color: green; + left: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 150; + document.getElementById('scroller2').scrollTop = 225; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div>You should see three green boxes below. No red should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 200px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-top.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-top.html new file mode 100644 index 0000000000..46931333c6 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-td-top.html @@ -0,0 +1,109 @@ +<!DOCTYPE html> +<title>position:sticky top constraint should behave correctly for <td> elements</title> +<link rel="match" href="position-sticky-table-td-top-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky top constraint behaves correctly for <td> elements" /> + +<style> +table { + border-collapse:collapse; +} + +td { + padding: 0; +} + +td > div { + height: 50px; + width: 50px; +} + +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.prepadding { + height: 100px; +} + +.postpadding { + height: 250px; +} + +.indicator { + position: absolute; + background-color: red; + left: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + top: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 150; + document.getElementById('scroller2').scrollTop = 225; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div>You should see three green boxes below. No red should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 200px;"></div> + <div class="prepadding"></div> + <table> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td class="sticky"><div></div></td></tr> + <tr><td><div></div></td></tr> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td class="sticky"><div></div></td></tr> + <tr><td><div></div></td></tr> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td class="sticky"><div></div></td></tr> + <tr><td><div></div></td></tr> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tfoot-bottom-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tfoot-bottom-ref.html new file mode 100644 index 0000000000..a1ee8e79f1 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tfoot-bottom-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky bottom constraint should behave correctly for <tfoot> elements</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 550px; +} + +.indicator { + position: absolute; + background-color: green; + left: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 0; + document.getElementById('scroller2').scrollTop = 75; + document.getElementById('scroller3').scrollTop = 200; +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tfoot-bottom.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tfoot-bottom.html new file mode 100644 index 0000000000..4ddd0cb78e --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tfoot-bottom.html @@ -0,0 +1,124 @@ +<!DOCTYPE html> +<title>position:sticky bottom constraint should behave correctly for <tfoot> elements</title> +<link rel="match" href="position-sticky-table-tfoot-bottom-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky bottom constraint behaves correctly for <tfoot> elements" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +table { + border-collapse:collapse; +} + +td, th { + padding: 0; +} + +td > div, th > div { + height: 50px; + width: 50px; +} + +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.prepadding { + height: 100px; +} + +.postpadding { + height: 250px; +} + +.indicator { + position: absolute; + background-color: red; + left: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + bottom: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 0; + document.getElementById('scroller2').scrollTop = 75; + document.getElementById('scroller3').scrollTop = 200; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + <tfoot class="sticky"> + <tr><th><div></div></th></tr> + </tfoot> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + <tfoot class="sticky"> + <tr><th><div></div></th></tr> + </tfoot> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + <tfoot class="sticky"> + <tr><th><div></div></th></tr> + </tfoot> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-bottom-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-bottom-ref.html new file mode 100644 index 0000000000..341a75ca34 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-bottom-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky bottom constraint should behave correctly for <th> elements</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 550px; +} + +.indicator { + position: absolute; + background-color: green; + left: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 0; + document.getElementById('scroller2').scrollTop = 75; + document.getElementById('scroller3').scrollTop = 200; +}); +</script> + +<div>You should see three green boxes below. No red should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-bottom.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-bottom.html new file mode 100644 index 0000000000..bd6a824317 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-bottom.html @@ -0,0 +1,127 @@ +<!DOCTYPE html> +<title>position:sticky bottom constraint should behave correctly for <th> elements</title> +<link rel="match" href="position-sticky-table-th-bottom-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky bottom constraint behaves correctly for <th> elements" /> + +<style> +table { + border-collapse:collapse; +} + +td, th { + padding: 0; +} + +td > div, th > div { + height: 50px; + width: 50px; +} + +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.prepadding { + height: 100px; +} + +.postpadding { + height: 250px; +} + +.indicator { + position: absolute; + background-color: red; + left: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + bottom: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 0; + document.getElementById('scroller2').scrollTop = 75; + document.getElementById('scroller3').scrollTop = 200; +}); +</script> + +<div>You should see three green boxes below. No red should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + <tfoot> + <tr> + <th class="sticky"><div></div></th> + </tr> + </tfoot> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + <tfoot> + <tr> + <th class="sticky"><div></div></th> + </tr> + </tfoot> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + <tfoot> + <tr> + <th class="sticky"><div></div></th> + </tr> + </tfoot> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-left-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-left-ref.html new file mode 100644 index 0000000000..7d0e5f9e58 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-left-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky left constraint should behave correctly for <th> elements</title> + +<style> +.group { + position: relative; + width: 250px; + height: 150px; +} + +.scroller { + position: relative; + width: 200px; + height: 100px; + overflow-x: auto; + overflow-y: hidden; +} + +.contents { + height: 10px; + width: 500px; +} + +.indicator { + position: absolute; + background-color: green; + top: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 50; + document.getElementById('scroller2').scrollLeft = 125; + document.getElementById('scroller3').scrollLeft = 250; +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="left: 100px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="left: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="left: 250px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-left.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-left.html new file mode 100644 index 0000000000..7361b25ce6 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-left.html @@ -0,0 +1,118 @@ +<!DOCTYPE html> +<title>position:sticky left constraint should behave correctly for <th> elements</title> +<link rel="match" href="position-sticky-table-th-left-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky left constraint behaves correctly for <th> elements" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +table { + border-collapse: collapse; + margin-left: 100px; +} + +td, th { + padding: 0; +} + +td > div, th > div { + height: 50px; + width: 50px; +} + +.group { + position: relative; + width: 250px; + height: 150px; +} + +.scroller { + position: relative; + width: 200px; + height: 100px; + overflow-x: auto; + overflow-y: hidden; +} + +.postpadding { + height: 10px; + width: 500px; +} + +.indicator { + position: absolute; + background-color: red; + top: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + left: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 50; + document.getElementById('scroller2').scrollLeft = 125; + document.getElementById('scroller3').scrollLeft = 250; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="left: 100px;"></div> + <table> + <tbody> + <tr> + <th class="sticky"><div></div></th> + <td><div></div></td> + <td><div></div></td> + <td><div></div></td> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="left: 150px;"></div> + <table> + <tbody> + <tr> + <th class="sticky"><div></div></th> + <td><div></div></td> + <td><div></div></td> + <td><div></div></td> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="left: 250px;"></div> + <table> + <tbody> + <tr> + <th class="sticky"><div></div></th> + <td><div></div></td> + <td><div></div></td> + <td><div></div></td> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-right-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-right-ref.html new file mode 100644 index 0000000000..760376f10c --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-right-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky right constraint should behave correctly for <th> elements</title> + +<style> +.group { + position: relative; + width: 250px; + height: 150px; +} + +.scroller { + position: relative; + width: 200px; + height: 100px; + overflow-x: auto; + overflow-y: hidden; +} + +.contents { + height: 10px; + width: 500px; +} + +.indicator { + position: absolute; + background-color: green; + top: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 0; + document.getElementById('scroller2').scrollLeft = 75; + document.getElementById('scroller3').scrollLeft = 200; +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="left: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="left: 200px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="left: 300px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-right.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-right.html new file mode 100644 index 0000000000..a1598f5506 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-right.html @@ -0,0 +1,118 @@ +<!DOCTYPE html> +<title>position:sticky right constraint should behave correctly for <th> elements</title> +<link rel="match" href="position-sticky-table-th-right-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky right constraint behaves correctly for <th> elements" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +table { + border-collapse: collapse; + margin-left: 150px; +} + +td, th { + padding: 0; +} + +td > div, th > div { + height: 50px; + width: 50px; +} + +.group { + position: relative; + width: 250px; + height: 150px; +} + +.scroller { + position: relative; + width: 200px; + height: 100px; + overflow-x: auto; + overflow-y: hidden; +} + +.postpadding { + height: 10px; + width: 500px; +} + +.indicator { + position: absolute; + background-color: red; + top: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + right: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollLeft = 0; + document.getElementById('scroller2').scrollLeft = 75; + document.getElementById('scroller3').scrollLeft = 200; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="left: 150px;"></div> + <table> + <tbody> + <tr> + <td><div></div></td> + <td><div></div></td> + <td><div></div></td> + <th class="sticky"><div></div></th> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="left: 200px;"></div> + <table> + <tbody> + <tr> + <td><div></div></td> + <td><div></div></td> + <td><div></div></td> + <th class="sticky"><div></div></th> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="left: 300px;"></div> + <table> + <tbody> + <tr> + <td><div></div></td> + <td><div></div></td> + <td><div></div></td> + <th class="sticky"><div></div></th> + </tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-top-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-top-ref.html new file mode 100644 index 0000000000..c9058c5522 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-top-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky top constraint should behave correctly for <th> elements</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 550px; +} + +.indicator { + position: absolute; + background-color: green; + left: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div>You should see three green boxes below. No red should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-top.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-top.html new file mode 100644 index 0000000000..57ff489e03 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-th-top.html @@ -0,0 +1,127 @@ +<!DOCTYPE html> +<title>position:sticky top constraint should behave correctly for <th> elements</title> +<link rel="match" href="position-sticky-table-th-top-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky top constraint behaves correctly for <th> elements" /> + +<style> +table { + border-collapse:collapse; +} + +td, th { + padding: 0; +} + +td > div, th > div { + height: 50px; + width: 50px; +} + +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.prepadding { + height: 100px; +} + +.postpadding { + height: 250px; +} + +.indicator { + position: absolute; + background-color: red; + left: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + top: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div>You should see three green boxes below. No red should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="prepadding"></div> + <table> + <thead> + <tr> + <th class="sticky"><div></div></th> + </tr> + </thead> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="prepadding"></div> + <table> + <thead> + <tr> + <th class="sticky"><div></div></th> + </tr> + </thead> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <thead> + <tr> + <th class="sticky"><div></div></th> + </tr> + </thead> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-thead-top-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-thead-top-ref.html new file mode 100644 index 0000000000..d952c13b3b --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-thead-top-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky top constraint should behave correctly for <thead> elements</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 550px; +} + +.indicator { + position: absolute; + background-color: green; + left: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-thead-top.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-thead-top.html new file mode 100644 index 0000000000..13c1b313c5 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-thead-top.html @@ -0,0 +1,124 @@ +<!DOCTYPE html> +<title>position:sticky top constraint should behave correctly for <thead> elements</title> +<link rel="match" href="position-sticky-table-thead-top-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky top constraint behaves correctly for <thead> elements" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +table { + border-collapse:collapse; +} + +td, th { + padding: 0; +} + +td > div, th > div { + height: 50px; + width: 50px; +} + +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.prepadding { + height: 100px; +} + +.postpadding { + height: 250px; +} + +.indicator { + position: absolute; + background-color: red; + left: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + top: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr><th><div></div></th></tr> + </thead> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr><th><div></div></th></tr> + </thead> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <thead class="sticky"> + <tr><th><div></div></th></tr> + </thead> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-bottom-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-bottom-ref.html new file mode 100644 index 0000000000..2f61ee6d3a --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-bottom-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky bottom constraint should behave correctly for <tr> elements</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 550px; +} + +.indicator { + position: absolute; + background-color: green; + left: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 0; + document.getElementById('scroller2').scrollTop = 75; + document.getElementById('scroller3').scrollTop = 200; +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-bottom.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-bottom.html new file mode 100644 index 0000000000..be9f1480a3 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-bottom.html @@ -0,0 +1,121 @@ +<!DOCTYPE html> +<title>position:sticky bottom constraint should behave correctly for <tr> elements</title> +<link rel="match" href="position-sticky-table-tr-bottom-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky bottom constraint behaves correctly for <tr> elements" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +table { + border-collapse:collapse; +} + +td { + padding: 0; +} + +td > div { + height: 50px; + width: 50px; +} + +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.prepadding { + height: 100px; +} + +.postpadding { + height: 250px; +} + +.indicator { + position: absolute; + background-color: red; + left: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + bottom: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 0; + document.getElementById('scroller2').scrollTop = 75; + document.getElementById('scroller3').scrollTop = 200; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<!-- .sticky element pushed as far up as possible to table edge --> +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr class="sticky"><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<!-- .sticky element stuck to bottom of .scroller --> +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr class="sticky"><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<!-- .sticky element unstuck --> +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr class="sticky"><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-top-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-top-ref.html new file mode 100644 index 0000000000..8b1989520b --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-top-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>Reference for position:sticky top constraint should behave correctly for <tr> elements</title> + +<style> +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.contents { + height: 550px; +} + +.indicator { + position: absolute; + background-color: green; + left: 0; + height: 50px; + width: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="contents"></div> + </div> +</div> + +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="contents"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-top.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-top.html new file mode 100644 index 0000000000..5e38ad38d9 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-table-tr-top.html @@ -0,0 +1,121 @@ +<!DOCTYPE html> +<title>position:sticky top constraint should behave correctly for <tr> elements</title> +<link rel="match" href="position-sticky-table-tr-top-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that the position:sticky top constraint behaves correctly for <tr> elements" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +table { + border-collapse:collapse; +} + +td { + padding: 0; +} + +td > div { + height: 50px; + width: 50px; +} + +.group { + display: inline-block; + position: relative; + width: 150px; + height: 200px; +} + +.scroller { + position: relative; + width: 100px; + height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.prepadding { + height: 100px; +} + +.postpadding { + height: 250px; +} + +.indicator { + position: absolute; + background-color: red; + left: 0; + height: 50px; + width: 50px; +} + +.sticky { + position: sticky; + top: 25px; + background-color: green; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller2').scrollTop = 125; + document.getElementById('scroller3').scrollTop = 250; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see three green boxes below. No red or blue should be visible.</div> + +<!-- .sticky element not yet stuck --> +<div class="group"> + <div id="scroller1" class="scroller"> + <div class="indicator" style="top: 100px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr class="sticky"><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<!-- .sticky element stuck to top of .scroller --> +<div class="group"> + <div id="scroller2" class="scroller"> + <div class="indicator" style="top: 150px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr class="sticky"><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> + +<!-- .sticky element pushed as down as possible to table edge --> +<div class="group"> + <div id="scroller3" class="scroller"> + <div class="indicator" style="top: 250px;"></div> + <div class="prepadding"></div> + <table> + <tbody> + <tr class="sticky"><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + <tr><td><div></div></td></tr> + </tbody> + </table> + <div class="postpadding"></div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-002.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-002.html new file mode 100644 index 0000000000..e8025d679e --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-002.html @@ -0,0 +1,121 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Position Test: sticky element with top offset specified with px unit</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + <link rel="match" href="reference/position-sticky-top-002-ref.html"> + + <meta name="flags" content=""> + + <style> + div.scrolling-container + { + background-image: url("support/100x100-red.png"); + background-repeat: no-repeat; + display: inline-block; + height: 250px; + margin-right: 30px; + overflow: auto; + position: static; + width: 150px; + } + + div#first-scrolling-container + { + background-position: left bottom; + } + + div#second-scrolling-container + { + background-position: left 100px; + } + + div#third-scrolling-container + { + background-position: left 50px; + } + + div.vertical-spacer + { + height: 100px; + } + + div.sticky + { + background-color: green; + height: 100px; + position: sticky; + top: 100px; + width: 100px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollTop = 50; document.getElementById("second-scrolling-container").scrollTop = 200; document.getElementById("third-scrolling-container").scrollTop = 300;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <!-- + first-scrolling-container: before reaching the sticking point + --> + + <div id="first-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="first-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <!-- + second-scrolling-container: when reaching the sticking point and beyond + --> + + <div id="second-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="second-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + + <div id="third-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="third-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-003.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-003.html new file mode 100644 index 0000000000..574b1b359b --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-003.html @@ -0,0 +1,121 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Position Test: sticky element with top offset specified with percentage unit</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + <link rel="match" href="reference/position-sticky-top-002-ref.html"> + + <meta name="flags" content=""> + + <style> + div.scrolling-container + { + background-image: url("support/100x100-red.png"); + background-repeat: no-repeat; + display: inline-block; + height: 250px; + margin-right: 30px; + overflow: auto; + position: static; + width: 150px; + } + + div#first-scrolling-container + { + background-position: left bottom; + } + + div#second-scrolling-container + { + background-position: left 100px; + } + + div#third-scrolling-container + { + background-position: left 50px; + } + + div.vertical-spacer + { + height: 100px; + } + + div.sticky + { + background-color: green; + height: 100px; + position: sticky; + top: 40%; + width: 100px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollTop = 50; document.getElementById("second-scrolling-container").scrollTop = 200; document.getElementById("third-scrolling-container").scrollTop = 300;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <!-- + first-scrolling-container: before reaching the sticking point + --> + + <div id="first-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="first-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <!-- + second-scrolling-container: when reaching the sticking point and beyond + --> + + <div id="second-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="second-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + + <div id="third-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div class="content"> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + <div id="third-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> + + <div class="vertical-spacer"></div> <!-- 150w x 100h --> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-and-bottom-003.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-and-bottom-003.html new file mode 100644 index 0000000000..af68bcef72 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-and-bottom-003.html @@ -0,0 +1,102 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Position Test: sticky element with top and bottom offsets specified with percentage unit</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos"> + <link rel="match" href="reference/position-sticky-top-and-bottom-003-ref.html"> + + <meta name="flags" content=""> + + <style> + div.scrolling-container + { + background-image: url("support/100x100-red.png"); + background-repeat: no-repeat; + display: inline-block; + height: 250px; + margin-right: 30px; + overflow: auto; + position: static; + width: 150px; + } + + div#first-scrolling-container + { + background-position: left 125px; + } + + div#second-scrolling-container + { + background-position: left 50px; + } + + div#third-scrolling-container + { + background-position: left 25px; + } + + div.vertical-spacer + { + height: 200px; + } + + div.sticky + { + background-color: green; + bottom: 10%; + height: 100px; + position: sticky; + top: 10%; + width: 100px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollTop = 50; document.getElementById("second-scrolling-container").scrollTop = 150; document.getElementById("third-scrolling-container").scrollTop = 250;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <!-- + first-scrolling-container: when reaching the first (top) sticking point + --> + + <div id="first-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 200h --> + + <div id="first-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 200h --> + + </div> + + <!-- + second-scrolling-container: between both sticking points + --> + + <div id="second-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 200h --> + + <div id="second-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 200h --> + + </div> + + <!-- + third-scrolling-container: when reaching the second (bottom) sticking point + --> + + + <div id="third-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 150w x 200h --> + + <div id="third-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 150w x 200h --> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-and-bottom.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-and-bottom.html new file mode 100644 index 0000000000..c790eaaf3e --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-and-bottom.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<title>position:sticky elements can be constrained by top and bottom exceeding container size</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements obey both top and bottom constraints" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> + +.scroller { + height: 200px; + overflow: auto; + position: relative; +} +.container { + height: 120px; +} +.padding, .sticky { + height: 50px; +} +.overflow-padding { + height: 200px; +} +.sticky { + position: sticky; + background: green; + top: -25px; + bottom: 150px; +} +</style> + +<body> + <div class="scroller"> + <div class="container"> + <div class="padding"></div> + <div class="sticky"></div> + </div> + <div class="overflow-padding"></div> + </div> +</body> + +<script> +test(() => { + const scroller = document.querySelector('.scroller'); + const element = document.querySelector('.sticky'); + scroller.scrollTop = 0; + assert_equals(element.offsetTop, 0); +}, 'initially the sticky box should be pushed to the top of the container'); + +test(() => { + const scroller = document.querySelector('.scroller'); + const element = document.querySelector('.sticky'); + scroller.scrollTop = 95; + assert_equals(element.offsetTop, 70); +}, 'when we scroll past the flow position the top constraint pushes it down'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-top.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top.html new file mode 100644 index 0000000000..9929fc734b --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<title>position:sticky elements should respect the top constraint</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky elements obey their top anchor after scrolling" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body></body> + +<script> +test(() => { + const elements = setupStickyTest('top', 50); + elements.scroller.scrollTop = 100; + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + assert_equals(elements.sticky.offsetTop, nonStickyTopY); +}, 'before reaching the sticking point the sticky box should not be offset'); + +test(() => { + const elements = setupStickyTest('top', 50); + elements.scroller.scrollTop = 200; + + // This math cancels to sticky.offsetTop == (scroller.scrollTop + 50), but + // for clarity the calculations are left explicit. + const nonStickyTopY = elements.container.offsetTop + + elements.filler.clientHeight; + const targetTopY = elements.scroller.scrollTop + 50; + const stickyOffset = targetTopY - nonStickyTopY; + + assert_equals(elements.sticky.offsetTop, nonStickyTopY + stickyOffset); +}, 'after reaching the sticking point the sticky box should be offset'); + +test(() => { + const elements = setupStickyTest('top', 50); + elements.scroller.scrollTop = 300; + const maxOffsetInContainer = elements.container.offsetTop + + elements.container.clientHeight - elements.sticky.clientHeight; + assert_equals(elements.sticky.offsetTop, maxOffsetInContainer); +}, 'the sticky box should not be pushed outside its containing block'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-transforms-translate.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-transforms-translate.html new file mode 100644 index 0000000000..fb2ca6b85f --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-transforms-translate.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<title>translations on position:sticky elements should apply after sticking</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that translations on position:sticky elements are carried out on their stuck position" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body style="margin: 0;"></body> + +<script> +test(() => { + const elements = setupStickyTest('top', 50); + elements.sticky.style.transform = 'translateY(-100%)'; + elements.scroller.scrollTop = 100; + // Transforms don't affect offsetTop, so use getBoundingClientRect. + assert_equals(elements.sticky.getBoundingClientRect().y, + elements.scroller.getBoundingClientRect().y); +}, 'Translation transform can move sticky element past sticking point'); + +test(() => { + const elements = setupStickyTest('top', 50); + elements.sticky.style.transform = 'translateY(50%)'; + elements.scroller.scrollTop = 200; + // Transforms don't affect offsetTop, so use getBoundingClientRect. + const stickyElementOffset = elements.sticky.getBoundingClientRect().y - + elements.scroller.getBoundingClientRect().y; + assert_equals(stickyElementOffset, 100); +}, 'Stuck elements can still be moved via translations'); + +test(() => { + const elements = setupStickyTest('top', 50); + elements.container.style.transform = 'translateY(100px)'; + elements.scroller.scrollTop = 200; + // Transforms don't affect offsetTop, so use getBoundingClientRect. + // Here the sticky element will originally have stuck at 50px from the top, + // but is then 'pulled' downwards by the 100px container transform. + const stickyElementOffset = elements.sticky.getBoundingClientRect().y - + elements.scroller.getBoundingClientRect().y; + assert_equals(stickyElementOffset, 150); +}, 'The sticky element should stick before the container is offset by a ' + + 'translation'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-transforms.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-transforms.html new file mode 100644 index 0000000000..080f05a4eb --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-transforms.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<title>transforms on position:sticky elements should apply after sticking</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that transforms on position:sticky elements are carried out on their stuck position" /> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="../resources/sticky-util.js"></script> + +<body style="margin: 0;"></body> + +<script> +test(() => { + const elements = setupStickyTest('top', 50); + elements.sticky.style.transform = 'scale(2)'; + elements.scroller.scrollTop = 200; + + // Transforms don't affect offsetTop, so use getBoundingClientRect. + // Scaling the sticky element by 2 means its top-y moves (1/2 * height) + // upwards, in this case placing it at the top of the viewport. + const boundingRect = elements.sticky.getBoundingClientRect(); + assert_equals(boundingRect.y, elements.scroller.getBoundingClientRect().y); +}, 'Scale transforms are carried out on the stuck element position'); + +test(() => { + const elements = setupStickyTest('top', 50); + elements.sticky.style.transform = 'rotateX(60deg)'; + elements.scroller.scrollTop = 200; + + // Transforms don't affect offsetTop, so use getBoundingClientRect. + // Rotating around the x-axis essentially 'squashes' it (from the camera's + // viewpoint), in this case shifting the offset to 75 rather than 50. + const stickyElementOffset = elements.sticky.getBoundingClientRect().y - + elements.scroller.getBoundingClientRect().y; + assert_equals(stickyElementOffset, 75); +}, 'Rotate transforms are carried out on the stuck element position'); + +test(() => { + const elements = setupStickyTest('top', 50); + elements.sticky.style.transform = 'perspective(3px) translateZ(1px)'; + elements.scroller.scrollTop = 200; + + // Transforms don't affect offsetTop, so use getBoundingClientRect. + const stickyElementOffset = elements.sticky.getBoundingClientRect().y - + elements.scroller.getBoundingClientRect().y; + assert_equals(stickyElementOffset, 25); +}, 'Perspective transforms are carried out on the stuck element position'); +</script> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-writing-modes-ref.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-writing-modes-ref.html new file mode 100644 index 0000000000..d55c22d953 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-writing-modes-ref.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<title>Reference for position:sticky constraints are independent of writing mode</title> + +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.group { + display: inline-block; + position: relative; + width: 180px; + height: 250px; +} + +.scroller { + position: relative; + width: 130px; + height: 200px; + overflow: hidden; + font: 30px/1 Ahem; +} + +.contents { + height: 500px; + width: 200px; +} + +.indicator { + display: inline; + color: green; + position: relative; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller1').scrollLeft = 20; + document.getElementById('scroller2').scrollTop = 50; + document.getElementById('scroller2').scrollLeft = -25; +}); +</script> + +<div>You should see two green blocks below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller" style="writing-mode: vertical-lr;"> + <div class="contents"> + <div class="indicator" style="left: 40px; top: 100px;">XXX</div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller" style="writing-mode: vertical-rl;"> + <div class="contents"> + <div class="indicator" style="right: 45px; top: 100px;">XXX</div> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-writing-modes.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-writing-modes.html new file mode 100644 index 0000000000..98f50500b8 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-writing-modes.html @@ -0,0 +1,73 @@ +<!DOCTYPE html> +<title>position:sticky constraints are independent of writing mode</title> +<link rel="match" href="position-sticky-writing-modes-ref.html" /> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> +<meta name="assert" content="This test checks that position:sticky constraints are independent of the writing mode" /> + +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + +<script src="../resources/ref-rectangle.js"></script> + +<style> +.group { + display: inline-block; + position: relative; + width: 180px; + height: 250px; +} + +.scroller { + position: relative; + width: 130px; + height: 200px; + overflow: hidden; + font: 30px/1 Ahem; +} + +.contents { + height: 500px; + width: 200px; +} + +.indicator { + position: absolute; + color: red; +} + +.sticky { + display: inline; + color: green; + position: sticky; + top: 50px; +} +</style> + +<script> +window.addEventListener('load', function() { + document.getElementById('scroller1').scrollTop = 50; + document.getElementById('scroller1').scrollLeft = 20; + document.getElementById('scroller2').scrollTop = 50; + document.getElementById('scroller2').scrollLeft = -25; + createIndicatorForStickyElements(document.querySelectorAll('.sticky')); +}); +</script> + +<div>You should see two green blocks below. No red or blue should be visible.</div> + +<div class="group"> + <div id="scroller1" class="scroller" style="writing-mode: vertical-lr;"> + <div class="indicator" style="left: 40px; top: 100px;">XXX</div> + <div class="contents"> + <div class="sticky" style="left: 20px;">XXX</div> + </div> + </div> +</div> + +<div class="group"> + <div id="scroller2" class="scroller" style="writing-mode: vertical-rl;"> + <div class="indicator" style="left: 55px; top: 100px;">XXX</div> + <div class="contents"> + <div class="sticky" style="right: 20px;">XXX</div> + </div> + </div> +</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-bottom-002-ref.html b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-bottom-002-ref.html new file mode 100644 index 0000000000..253ca7eebe --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-bottom-002-ref.html @@ -0,0 +1,78 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Reftest Reference</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + + <style> + div.scrolling-container + { + display: inline-block; + height: 250px; + margin-right: 30px; + overflow: auto; + position: static; + width: 150px; + } + + div.vertical-spacer-200 + { + height: 200px; + } + + div.sticky + { + background-color: green; + height: 100px; + position: relative; + width: 100px; + } + + div#first-sticky + { + bottom: 100px; + } + + div#second-sticky + { + bottom: 50px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollTop = 25; document.getElementById("second-scrolling-container").scrollTop = 100; document.getElementById("third-scrolling-container").scrollTop = 200;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <div id="first-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + <div id="first-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + </div> + + + <div id="second-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + <div id="second-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + </div> + + + <div id="third-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + <div id="third-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-fixed-ancestor-002-ref.html b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-fixed-ancestor-002-ref.html new file mode 100644 index 0000000000..abdc1dbcfa --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-fixed-ancestor-002-ref.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Reference File</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + + <style> + html, body, div + { + background-color: green; + color: white; + font-size: 40vh; + height: 100%; + margin: 0; + } + </style> + + <div>PASS</div> diff --git a/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-left-002-ref.html b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-left-002-ref.html new file mode 100644 index 0000000000..75aa9a4c1f --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-left-002-ref.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Reftest Reference</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + + <style> + div.scrolling-container + { + height: 150px; + margin-bottom: 30px; + overflow-y: hidden; + position: static; + white-space: nowrap; + width: 250px; + } + + div.horizontal-spacer-200 + { + display: inline-block; + height: 100%; + width: 200px; + } + + div.sticky + { + background-color: green; + display: inline-block; + height: 100px; + position: relative; + vertical-align: top; + width: 100px; + } + + div#first-sticky + { + left: 0px; + } + + div#second-sticky + { + left: 50px; + } + + div#third-sticky + { + left: 100px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollLeft = 50; document.getElementById("second-scrolling-container").scrollLeft = 150; document.getElementById("third-scrolling-container").scrollLeft = 300;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <div id="first-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer-200"></div><div id="first-sticky" class="sticky"></div><div class="horizontal-spacer-200"></div> + + </div> + + + <div id="second-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer-200"></div><div id="second-sticky" class="sticky"></div><div class="horizontal-spacer-200"></div> + + </div> + + <div id="third-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer-200"></div><div id="third-sticky" class="sticky"></div><div class="horizontal-spacer-200"></div> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-right-002-ref.html b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-right-002-ref.html new file mode 100644 index 0000000000..3230e476b5 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-right-002-ref.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Reftest Reference</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + + <style> + div.scrolling-container + { + height: 150px; + margin-bottom: 30px; + overflow-y: hidden; + position: static; + white-space: nowrap; + width: 250px; + } + + div.horizontal-spacer-200 + { + display: inline-block; + height: 100%; + width: 200px; + } + + div.sticky + { + background-color: green; + display: inline-block; + height: 100px; + position: relative; + vertical-align: top; + width: 100px; + } + + div#first-sticky + { + right: 100px; + } + + div#second-sticky + { + right: 50px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollLeft = 25; document.getElementById("second-scrolling-container").scrollLeft = 100; document.getElementById("third-scrolling-container").scrollLeft = 200;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <div id="first-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer-200"></div><div id="first-sticky" class="sticky"></div><div class="horizontal-spacer-200"></div> + + </div> + + <div id="second-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer-200"></div><div id="second-sticky" class="sticky"></div><div class="horizontal-spacer-200"></div> + + </div> + + <div id="third-scrolling-container" class="scrolling-container"> + + <div class="horizontal-spacer-200"></div><div id="third-sticky" class="sticky"></div><div class="horizontal-spacer-200"></div> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-top-002-ref.html b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-top-002-ref.html new file mode 100644 index 0000000000..4a95591a56 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-top-002-ref.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Reftest Reference</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + + <style> + div.scrolling-container + { + display: inline-block; + height: 250px; + margin-right: 30px; + overflow: auto; + position: static; + width: 150px; + } + + div.vertical-spacer-200 + { + height: 200px; + } + + div.sticky + { + background-color: green; + height: 100px; + position: relative; + width: 100px; + } + + div#first-sticky + { + top: 0px; + } + + div#second-sticky + { + top: 100px; + } + + div#third-sticky + { + top: 100px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollTop = 50; document.getElementById("second-scrolling-container").scrollTop = 200; document.getElementById("third-scrolling-container").scrollTop = 300;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <div id="first-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + <div id="first-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + </div> + + + <div id="second-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + <div id="second-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + </div> + + + <div id="third-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + <div id="third-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer-200"></div> <!-- 100w x 200h --> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-top-and-bottom-003-ref.html b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-top-and-bottom-003-ref.html new file mode 100644 index 0000000000..36af9a33bc --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/reference/position-sticky-top-and-bottom-003-ref.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Reftest Reference</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + + <style> + div.scrolling-container + { + display: inline-block; + height: 250px; + margin-right: 30px; + overflow: auto; + position: static; + width: 150px; + } + + div.vertical-spacer + { + height: 200px; + } + + div.sticky + { + background-color: green; + height: 100px; + position: relative; + width: 100px; + } + + div#first-sticky + { + bottom: 25px; + } + + div#second-sticky + { + top: 0px; + } + + div#third-sticky + { + top: 75px; + } + </style> + + <body onload="document.getElementById("first-scrolling-container").scrollTop = 50; document.getElementById("second-scrolling-container").scrollTop = 150; document.getElementById("third-scrolling-container").scrollTop = 250;"> + + <p>Test passes if there are 3 filled green squares and <strong>no red</strong>. + + <div id="first-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 100w x 200h --> + + <div id="first-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 100w x 200h --> + + </div> + + + <div id="second-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 100w x 200h --> + + <div id="second-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 100w x 200h --> + + </div> + + + <div id="third-scrolling-container" class="scrolling-container"> <!-- 150w x 250h viewport --> + + <div class="vertical-spacer"></div> <!-- 100w x 200h --> + + <div id="third-sticky" class="sticky"></div> <!-- 100w x 100h --> + + <div class="vertical-spacer"></div> <!-- 100w x 200h --> + + </div> diff --git a/testing/web-platform/tests/css/css-position/sticky/sticky-after-input.html b/testing/web-platform/tests/css/css-position/sticky/sticky-after-input.html new file mode 100644 index 0000000000..9104aa3c5e --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/sticky-after-input.html @@ -0,0 +1,49 @@ +<!doctype html> +<title>Sticky positioned element should reset the scroll position to unshifted position</title> +<link rel="author" title="Seokho Song" href="mailto:0xdevssh@gmail.com"> +<link rel="help" href="https://crbug.com/664246"> +<link rel="help" href="https://crbug.com/1178622"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> + +<div id="scrollEl" style="height:100px; overflow-y: auto; scroll-padding:20px 20px 20px 20px;"> + <input id="stickyEl" type="text" style="position:sticky;top:0" /> + <div>1</div> + <div>2</div> + <div>3</div> + <div>4</div> + <div>5</div> + <div>6</div> + <div>7</div> + <div>8</div> + <div>9</div> + <div>10</div> + <div>11</div> + <div>12</div> + <div>13</div> + <div>14</div> + <div>15</div> + <div>16</div> + <div>17</div> +</div> +</div> +<script> + +async_test(t => { + var scrollEl = document.getElementById("scrollEl"); + var stickyEl = document.getElementById("stickyEl"); + stickyEl.focus() + scrollEl.scrollTo(0, scrollEl.scrollHeight); + scrollEl.addEventListener('input', ()=> { + requestAnimationFrame(t.step_func(()=>{ + assert_equals(scrollEl.scrollTop, 0, + "should reset the scroll to unshifted sticky position"); + t.done() + })) + }) + test_driver.send_keys(stickyEl, "A") +}) +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/css/css-position/sticky/support/100x100-red.png b/testing/web-platform/tests/css/css-position/sticky/support/100x100-red.png Binary files differnew file mode 100644 index 0000000000..57bf3ddc52 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/support/100x100-red.png |