103 lines
3 KiB
HTML
103 lines
3 KiB
HTML
<!doctype HTML>
|
|
<html>
|
|
<meta charset="utf8">
|
|
<title>Content Visibility: off-screen focus</title>
|
|
<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
|
|
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
|
|
<meta name="assert" content="content-visibility auto element remains non-skipped when elements in its subtree have focus.">
|
|
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
|
|
<style>
|
|
body, html {
|
|
padding: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
.spacer {
|
|
height: 3000px;
|
|
background: lightblue;
|
|
}
|
|
#container {
|
|
background: lightgreen;
|
|
contain-intrinsic-size: 50px 100px;
|
|
content-visibility: auto;
|
|
}
|
|
#focusable {
|
|
width: 10px;
|
|
height: 10px;
|
|
}
|
|
</style>
|
|
|
|
<div id=end tabindex=1></div>
|
|
<div class=spacer></div>
|
|
<div id=container>
|
|
<div id=focusable tabindex=0></div>
|
|
</div>
|
|
<div class=spacer></div>
|
|
|
|
<script>
|
|
async_test((t) => {
|
|
// Initially container should be 3000px offscreen with contained height 100px.
|
|
function step1() {
|
|
const r = container.getBoundingClientRect();
|
|
t.step(() => {
|
|
assert_equals(r.y, 3000, "step1 offset");
|
|
assert_equals(r.height, 100, "step1 height");
|
|
});
|
|
|
|
focusable.focus();
|
|
step_timeout(step2, 0);
|
|
}
|
|
// After focusing the subtree, the container should be somewhere closer than
|
|
// 3000px (scrolled into view) and the height should be 10px, since it no
|
|
// longer has containment.
|
|
function step2() {
|
|
const r = container.getBoundingClientRect();
|
|
t.step(() => {
|
|
assert_less_than(r.y, 3000, "step2 offset");
|
|
assert_equals(r.height, 10, "step2 height");
|
|
});
|
|
document.scrollingElement.scrollTop = 0;
|
|
requestAnimationFrame(step3);
|
|
}
|
|
// After scrolling the document back to the top, the container should be back
|
|
// at 3000px but because its subtree is still focused, it should have height
|
|
// 10px.
|
|
function step3() {
|
|
const r = container.getBoundingClientRect();
|
|
t.step(() => {
|
|
assert_equals(r.y, 3000, "step3 offset");
|
|
assert_equals(r.height, 10, "step3 height");
|
|
});
|
|
requestAnimationFrame(step4);
|
|
}
|
|
// This is a repeat of step3, to ensure that this is a stable state.
|
|
function step4() {
|
|
const r = container.getBoundingClientRect();
|
|
t.step(() => {
|
|
assert_equals(r.y, 3000, "step4 offset");
|
|
assert_equals(r.height, 10, "step4 height");
|
|
});
|
|
|
|
// We don't use `blur()` here because in Gecko this leaves the selection
|
|
// on _focusable_ which means that its content is still relevant. Focusing
|
|
// another element will move both focus and selection.
|
|
end.focus();
|
|
requestAnimationFrame(step5);
|
|
}
|
|
// After blurring the focused element, we keep the last rendered size, see
|
|
// https://github.com/w3c/csswg-drafts/issues/8407.
|
|
function step5() {
|
|
const r = container.getBoundingClientRect();
|
|
t.step(() => {
|
|
assert_equals(r.y, 3000, "step5 offset");
|
|
assert_equals(r.height, 10, "step5 height");
|
|
});
|
|
t.done();
|
|
}
|
|
step1();
|
|
});
|
|
</script>
|
|
</html>
|