<!DOCTYPE html>
<title>CSS Position: position:absolute dynamic containing block</title>
<link rel="author" title="mailto:[email protected]">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://drafts.csswg.org/css-position-3/#def-cb">
<meta name="assert" content="Tests changes in containing block for out-of-flow positioned descendants.">
<style>
#outer {
width: 400px;
height: 300px;
outline: black solid 1px;
}
#intermediate {
width: 300px;
height: 200px;
outline: gray solid 1px;
}
#target {
background: green;
}
.abs {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.fixed {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.abs-container {
position: relative;
}
.fixed-container {
will-change: transform;
}
div {
padding: 5px;
}
</style>
<!-- This tests potential caching of out-of-flow positioned descendants. -->
<div id="outer">
<div>
<div id="intermediate">
<div>
<div id="target">TTT</div>
<div id="noLayout1"></div>
</div>
<div id="noLayout2"></div>
</div>
</div>
</div>
<script>
let outer = document.querySelector("#outer");
let intermediate = document.querySelector("#intermediate");
let target = document.querySelector("#target");
let padding = 5;
function cleanup() {
outer.className = "";
intermediate.className = "";
target.className = "";
document.body.offsetTop;
}
test( t => {
t.add_cleanup(cleanup);
outer.classList.add("abs-container");
target.classList.add("abs");
assert_equals(target.offsetHeight, outer.offsetHeight);
intermediate.classList.add("abs-container");
assert_equals(target.offsetHeight, intermediate.offsetHeight);
}, "abs containing block moves from outer to intermediate" );
test( t => {
t.add_cleanup(cleanup);
target.classList.add("abs");
intermediate.classList.add("abs-container");
assert_equals(target.offsetHeight, intermediate.offsetHeight);
outer.classList.add("abs-container");
assert_equals(target.offsetHeight, intermediate.offsetHeight);
intermediate.classList.remove("abs-container");
assert_equals(target.offsetHeight, outer.offsetHeight);
}, "abs containing block moves from intermediate to outer" );
test( t => {
t.add_cleanup(cleanup);
target.classList.add("abs");
outer.classList.add("abs-container");
assert_equals(target.offsetHeight, outer.offsetHeight);
target.classList.remove("abs");
assert_equals(target.offsetWidth, intermediate.offsetWidth - 4 * padding);
}, "target is no longer absolute");
test( t => {
t.add_cleanup(cleanup);
outer.classList.add("abs-container");
assert_equals(target.offsetWidth, intermediate.offsetWidth - 4 * padding);
target.classList.add("abs");
assert_equals(target.offsetHeight, outer.offsetHeight);
}, "target becomes absolute");
// Repeat same tests with fixed
test( t => {
t.add_cleanup(cleanup);
outer.classList.add("fixed-container");
target.classList.add("fixed");
assert_equals(target.offsetHeight, outer.offsetHeight);
intermediate.classList.add("fixed-container");
assert_equals(target.offsetHeight, intermediate.offsetHeight);
}, "fixed containing block moves from outer to intermediate" );
test( t => {
t.add_cleanup(cleanup);
target.classList.add("fixed");
intermediate.classList.add("fixed-container");
assert_equals(target.offsetHeight, intermediate.offsetHeight);
outer.classList.add("fixed-container");
assert_equals(target.offsetHeight, intermediate.offsetHeight);
intermediate.classList.remove("fixed-container");
assert_equals(target.offsetHeight, outer.offsetHeight);
}, "fixed containing block moves from intermediate to outer" );
test( t => {
t.add_cleanup(cleanup);
target.classList.add("fixed");
outer.classList.add("fixed-container");
assert_equals(target.offsetHeight, outer.offsetHeight);
target.classList.remove("fixed");
assert_equals(target.offsetWidth, intermediate.offsetWidth - 4 * padding);
}, "target is no longer fixed");
test( t => {
t.add_cleanup(cleanup);
outer.classList.add("fixed-container");
assert_equals(target.offsetWidth, intermediate.offsetWidth - 4 * padding);
target.classList.add("fixed");
assert_equals(target.offsetHeight, outer.offsetHeight);
}, "target becomes fixed");
</script>