Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!DOCTYPE html>
<meta charset="utf-8">
<title>content-visibility and layout/paint containment</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/rendering-utils.js"></script>
<meta name="assert" content="content-visibility: auto and elements skipping their content change the used value of the contain property to turn on layout/paint containment, affecting absolute/fixed positioned descendants.">
<style>
/* Selectors for content-visibility */
#spacer_for_far_to_viewport {
height: 300vh;
}
.content_visibility {
/* Dynamic modification of content-visibility may change whether style
containment is applied, which in turn may cause drastic invalidations
(e.g. rebuilding counters). Make the test more robust by forcing
style containment to always apply. */
contain: style;
}
#visible {
content-visibility: visible;
}
#hidden {
content-visibility: hidden;
}
#auto_far {
content-visibility: auto;
}
#auto_close {
content-visibility: auto;
}
#visible_to_hidden {
content-visibility: visible;
}
#hidden_to_visible {
content-visibility: hidden;
}
#visible_to_auto {
content-visibility: visible;
}
#auto_to_visible {
content-visibility: auto;
}
/* Selectors for testing absolute/fixed positioning container blocks */
#top_spacer {
height: 100px;
background: lightgray;
}
.absolute_pos {
position: absolute;
top: 42px;
}
.fixed_pos {
position: fixed;
top: 42px;
}
</style>
<body>
<div id="log"></div>
<div id="top_spacer"></div>
<div id="visible" class="content_visibility">
<div class="absolute_pos"></div>
<div class="fixed_pos"></div>
</div>
<div id="hidden" class="content_visibility">
<div class="absolute_pos"></div>
<div class="fixed_pos"></div>
</div>
<div id="auto_close" class="content_visibility">
<div class="absolute_pos"></div>
<div class="fixed_pos"></div>
</div>
<div id="visible_to_hidden" class="content_visibility">
<div class="absolute_pos"></div>
<div class="fixed_pos"></div>
</div>
<div id="hidden_to_visible" class="content_visibility">
<div class="absolute_pos"></div>
<div class="fixed_pos"></div>
</div>
<div id="visible_to_auto" class="content_visibility">
<div class="absolute_pos"></div>
<div class="fixed_pos"></div>
</div>
<div id="auto_to_visible" class="content_visibility">
<div class="absolute_pos"></div>
<div class="fixed_pos"></div>
</div>
<div id="spacer_for_far_to_viewport"></div>
<div id="auto_far" class="content_visibility">
<div class="absolute_pos"></div>
<div class="fixed_pos"></div>
</div>
<script>
function verifyContainmentFromAbsoluteFixedPositioning(id, applied) {
// content-visibility: auto and elements skipping their content change
// apply paint/layout containment, making them an absolute/fixed
// positioning container blocks.
// See contain-paint-dynamic-001.html / contain-layout-dynamic-001.html.
let container = document.getElementById(id);
let containerTop = container.getBoundingClientRect().top;
let abs_top = container.getElementsByClassName("absolute_pos")[0]
.getBoundingClientRect().top;
assert_equals(abs_top > containerTop, applied, "absolute positioning containing block");
let fixed_top = container.getElementsByClassName("fixed_pos")[0]
.getBoundingClientRect().top;
assert_equals(fixed_top > containerTop, applied, "fixed positioning containing block");
}
function setContentVisibility(id, value) {
let container = document.getElementById(id);
container.style.contentVisibility = value;
}
promise_test(async () => {
verifyContainmentFromAbsoluteFixedPositioning("visible",
/*applied=*/false);
}, "content-visibility: visible");
promise_test(async () => {
verifyContainmentFromAbsoluteFixedPositioning("hidden",
/*applied=*/true);
}, "content-visibility: hidden");
promise_test(async () => {
await waitForAtLeastOneFrame();
verifyContainmentFromAbsoluteFixedPositioning("auto_far",
/*applied=*/true);
}, "content-visibility: auto (far from viewport)");
promise_test(async () => {
await waitForAtLeastOneFrame();
verifyContainmentFromAbsoluteFixedPositioning("auto_close",
/*applied=*/true);
}, "content-visibility: auto (close from viewport)");
promise_test(async () => {
setContentVisibility("visible_to_hidden", "hidden");
verifyContainmentFromAbsoluteFixedPositioning("visible_to_hidden",
/*applied=*/true);
}, "switching content-visibility from visible to hidden");
promise_test(async () => {
setContentVisibility("hidden_to_visible", "visible");
verifyContainmentFromAbsoluteFixedPositioning("hidden_to_visible",
/*applied=*/false);
}, "switching content-visibility from hidden to visible");
promise_test(async () => {
setContentVisibility("visible_to_auto", "auto");
await waitForAtLeastOneFrame();
verifyContainmentFromAbsoluteFixedPositioning("visible_to_auto",
/*applied=*/true);
}, "switching content-visibility from visible to auto");
promise_test(async () => {
setContentVisibility("auto_to_visible", "visible");
verifyContainmentFromAbsoluteFixedPositioning("auto_to_visible",
/*applied=*/false);
}, "switching content-visibility from auto to visible");
</script>
</body>