mirror of
https://github.com/servo/servo.git
synced 2025-08-09 07:25:35 +01:00
Update web-platform-tests to revision 8d1253647cfe3809ddf58a4ad7c9da5f26985d7e
This commit is contained in:
parent
553ff20468
commit
48c420fdb5
440 changed files with 6186 additions and 3542 deletions
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
||||
|
||||
<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>
|
||||
|
||||
<p>You should see three green boxes of varying size above. There should be no red or blue.</p>
|
|
@ -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>
|
||||
|
||||
<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>
|
||||
|
||||
<p>You should see three green boxes of varying size above. There should be no red or blue.</p>
|
|
@ -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>
|
|
@ -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>
|
||||
|
||||
<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>
|
||||
|
||||
<p>You should see three green boxes of varying size above. There should be no red or blue.</p>
|
||||
|
|
@ -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>
|
||||
|
||||
<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>
|
||||
|
||||
<p>You should see three green boxes of varying size above. There should be no red or blue.</p>
|
|
@ -0,0 +1,35 @@
|
|||
<!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 class='scroller'>
|
||||
<a href='#' class='positioned'>Link</a>
|
||||
<div class='spacer'></div>
|
||||
</div>
|
||||
<div>You should see a sticky link at the top of the scrollable area.</div>
|
|
@ -0,0 +1,39 @@
|
|||
<!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 class='scroller'>
|
||||
<a href='#' class='sticky'>Link</a>
|
||||
<div class='spacer'></div>
|
||||
</div>
|
||||
<div>You should see a sticky link at the top of the scrollable area.</div>
|
|
@ -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>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green rectangles above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green rectangles above. No red or blue should be visible.</div>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Focusing on visible sticky input box should not scroll the page.</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, 100);
|
||||
}, 'Focusing on visible sticky input box should not scroll the page.');
|
||||
</script>
|
|
@ -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;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.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>
|
|
@ -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>
|
|
@ -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;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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, 35);
|
||||
}, '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, 35);
|
||||
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, 500);
|
||||
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>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green and three yellow rectangles above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green and three yellow rectangles above. No red or blue should be visible.</div>
|
|
@ -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>
|
|
@ -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, 35);
|
||||
}, '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, 35);
|
||||
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>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green rectangles above. No red or blue should be visible.</div>
|
|
@ -0,0 +1,134 @@
|
|||
<!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;
|
||||
createIndicatorForStickyElements(document.querySelectorAll('.sticky'));
|
||||
});
|
||||
</script>
|
||||
|
||||
<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>
|
||||
|
||||
<div>You should see three green rectangles above. No red or blue should be visible.</div>
|
|
@ -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>
|
|
@ -0,0 +1,60 @@
|
|||
<!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
|
||||
can cause overflow but must still be accessible through scrolling" />
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
overflow: 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>
|
||||
|
||||
<div id="scroller2" 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, 200);
|
||||
assert_equals(scroller.scrollHeight, 250);
|
||||
}, 'sticky position offset should be able to cause overflow');
|
||||
|
||||
test(() => {
|
||||
var scroller = document.getElementById('scroller2');
|
||||
var sticky = scroller.querySelector('.sticky');
|
||||
|
||||
scroller.scrollTop = 150;
|
||||
var stickyOffset = sticky.offsetTop -
|
||||
scroller.scrollTop - scroller.offsetTop;
|
||||
assert_equals(stickyOffset, 50);
|
||||
// Scroll height should be unaffected.
|
||||
assert_equals(scroller.scrollHeight, 250);
|
||||
|
||||
}, 'sticky position offset in overflow should be accessible');
|
||||
</script>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -0,0 +1,73 @@
|
|||
<!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>
|
||||
// Sticky is valid for all elements except table-column-group and table-column.
|
||||
const VALID_STICKY_DISPLAY_TYPES = [
|
||||
'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',
|
||||
'ruby-base',
|
||||
'ruby-text',
|
||||
'ruby-base-container',
|
||||
'ruby-text-container',
|
||||
'contents',
|
||||
'none',
|
||||
];
|
||||
|
||||
const INVALID_STICKY_DISPLAY_TYPES = [
|
||||
'table-column-group',
|
||||
'table-column',
|
||||
];
|
||||
|
||||
test(() => {
|
||||
for (displayValue of VALID_STICKY_DISPLAY_TYPES) {
|
||||
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);
|
||||
}
|
||||
|
||||
for (displayValue of INVALID_STICKY_DISPLAY_TYPES) {
|
||||
let div = document.createElement('div');
|
||||
let style = `position: sticky; display: ${displayValue};`;
|
||||
div.setAttribute('style', style);
|
||||
document.body.appendChild(div);
|
||||
|
||||
assert_not_equals(getComputedStyle(div).position, 'sticky',
|
||||
`Expected sticky to be invalid for display: ${displayValue}`);
|
||||
document.body.removeChild(div);
|
||||
}
|
||||
}, 'The value of sticky for the position property should be parsed correctly');
|
||||
</script>
|
||||
|
|
@ -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 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>
|
||||
|
||||
<div>You should see four green squares above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see four green squares above. No red or blue should be visible.</div>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>position:sticky should operate correctly</title>
|
||||
<link rel="author" title="Mason Freed" href="mailto:masonfreed@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>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>position:sticky should operate correctly</title>
|
||||
<link rel="author" title="Mason Freed" href="mailto:masonfreed@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>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos">
|
||||
<p>Test passes if there is a filled green square, and no scrollbars</p>
|
||||
<div id="container" style="overflow:auto; width:100px; height:100px; background:red;">
|
||||
<div style="position:sticky; top:0; height:100px; background:green;"></div>
|
||||
<div id="bigItem" style="height:600px;"></div>
|
||||
</div>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
container.scrollTop = 600;
|
||||
requestAnimationFrame(()=>{
|
||||
requestAnimationFrame(()=>{
|
||||
bigItem.style.display = "none";
|
||||
test(()=> {
|
||||
assert_equals(container.scrollHeight, 100);
|
||||
}, "Sticky position and its overflow contribution");
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -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 class="indicator box"></div>
|
||||
|
||||
<div>You should see a single green box above. No red or blue should be visible.</div>
|
|
@ -0,0 +1,45 @@
|
|||
<!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 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>
|
||||
|
||||
<div>You should see a single green box above. No red or blue should be visible.</div>
|
|
@ -0,0 +1,48 @@
|
|||
<!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 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>
|
||||
<div>There should be a green square at the top of the scroll view and no red or blue visible.</div>
|
|
@ -0,0 +1,75 @@
|
|||
<!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 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>
|
||||
<div>There should be a green square at the top of the scroll view and no red or blue visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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>
|
||||
|
||||
<!-- .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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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 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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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>
|
||||
|
||||
<!-- .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>
|
||||
|
||||
<div>You should see three green boxes above. No red or blue should be visible.</div>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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: scroll;
|
||||
font: 25px/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 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>
|
||||
|
||||
<div>You should see two green blocks above. No red or blue should be visible.</div>
|
|
@ -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: scroll;
|
||||
font: 25px/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 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: 45px; top: 100px;">XXX</div>
|
||||
<div class="contents">
|
||||
<div class="sticky" style="right: 20px;">XXX</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>You should see two green blocks above. No red or blue should be visible.</div>
|
Loading…
Add table
Add a link
Reference in a new issue