Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 2 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /css/css-position/position-relative-016.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<title>CSS Position: percentage top on relatively positioned elements whose containing block is out-of-flow positioned</title>
<meta name="assert" content="A relatively positioned box with a percentage top resolves against its containing block's height when that containing block is out-of-flow positioned and has a non-auto height (percent, stretch, calc, or implicit from top+bottom). Out-of-flow containing blocks always have computed used dimensions, so the percentage resolves even when an ancestor's style height is auto.">
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body {
margin: 0;
}
.green {
width: 20px;
height: 20px;
background: green;
position: relative;
}
.fixed-cb {
position: relative;
height: 200px;
}
.auto-cb {
position: relative;
font: 20px/1 Ahem;
}
</style>
<!-- 1. abspos with height: 100%, top: 50% -->
<div class="fixed-cb">
<div id="t1-cb" style="position: absolute; height: 100%;">
<div class="green" id="t1" style="top: 50%;"></div>
</div>
</div>
<!-- 2. abspos with height: 50%, top: 50% -->
<div class="fixed-cb">
<div id="t2-cb" style="position: absolute; height: 50%;">
<div class="green" id="t2" style="top: 50%;"></div>
</div>
</div>
<!-- 3. abspos with height: stretch, top: 50% -->
<div class="fixed-cb">
<div id="t3-cb" style="position: absolute; height: stretch;">
<div class="green" id="t3" style="top: 50%;"></div>
</div>
</div>
<!-- 4. abspos with height: calc(100% - 0px), top: 50% -->
<div class="fixed-cb">
<div id="t4-cb" style="position: absolute; height: calc(100% - 0px);">
<div class="green" id="t4" style="top: 50%;"></div>
</div>
</div>
<!-- 5. abspos with height: calc(50% + 50px), top: 50% -->
<div class="fixed-cb">
<div id="t5-cb" style="position: absolute; height: calc(50% + 50px);">
<div class="green" id="t5" style="top: 50%;"></div>
</div>
</div>
<!-- 6. abspos with height: 100%, display: inline, top: 50% -->
<div class="fixed-cb">
<div id="t6-cb" style="position: absolute; height: 100%; display: inline;">
<div class="green" id="t6" style="top: 50%;"></div>
</div>
</div>
<!-- 7. abspos with height: 100%, display: inline-block, top: 50% -->
<div class="fixed-cb">
<div id="t7-cb" style="position: absolute; height: 100%; display: inline-block;">
<div class="green" id="t7" style="top: 50%;"></div>
</div>
</div>
<!-- 8. abspos in auto-height ancestor (Ahem 20px line), height: 100%, top: 50% -->
<div class="auto-cb">x<div id="t8-cb" style="position: absolute; height: 100%;">
<div class="green" id="t8" style="top: 50%;"></div>
</div></div>
<!-- 9. abspos in auto-height ancestor, height: 100%, display: inline, top: 100% (regression case) -->
<div class="auto-cb">x<div id="t9-cb" style="position: absolute; height: 100%; display: inline;">
<div class="green" id="t9" style="top: 100%;"></div>
</div></div>
<!-- 10. Nested abspos containing blocks, top: 50% -->
<div class="fixed-cb">
<div style="position: absolute; height: 100%;">
<div id="t10-cb" style="position: absolute; height: 100%;">
<div class="green" id="t10" style="top: 50%;"></div>
</div>
</div>
</div>
<!-- 11. abspos inside abspos with fixed height, top: 50% -->
<div class="fixed-cb">
<div style="position: absolute; height: 100px;">
<div id="t11-cb" style="position: absolute; height: 100%;">
<div class="green" id="t11" style="top: 50%;"></div>
</div>
</div>
</div>
<!-- 12. abspos in percentage chain, top: 50% -->
<div class="fixed-cb">
<div style="position: relative; height: 50%;">
<div id="t12-cb" style="position: absolute; height: 100%;">
<div class="green" id="t12" style="top: 50%;"></div>
</div>
</div>
</div>
<!-- 13. abspos with bottom: auto, top: 50% (negative -- NOT definite) -->
<div class="fixed-cb">
<div id="t13-cb" style="position: absolute; top: 0;">
<div class="green" id="t13" style="top: 50%;"></div>
</div>
</div>
<!-- 14. abspos with min-height: 100%, height: auto, top: 50% (negative -- NOT definite) -->
<div class="fixed-cb">
<div id="t14-cb" style="position: absolute; min-height: 100%;">
<div class="green" id="t14" style="top: 50%;"></div>
</div>
</div>
<!-- 15. abspos with bottom: auto + height: auto + top: auto (default OOF) -->
<div class="fixed-cb">
<div id="t15-cb" style="position: absolute;">
<div class="green" id="t15" style="top: 50%;"></div>
</div>
</div>
<!-- 16. abspos with height: 100%, child bottom: 50% -->
<div class="fixed-cb">
<div id="t16-cb" style="position: absolute; height: 100%;">
<div class="green" id="t16" style="bottom: 50%;"></div>
</div>
</div>
<!-- 17. abspos with height: 50%, child bottom: 50% -->
<div class="fixed-cb">
<div id="t17-cb" style="position: absolute; height: 50%;">
<div class="green" id="t17" style="bottom: 50%;"></div>
</div>
</div>
<!-- 18. abspos with height: stretch, child bottom: 50% -->
<div class="fixed-cb">
<div id="t18-cb" style="position: absolute; height: stretch;">
<div class="green" id="t18" style="bottom: 50%;"></div>
</div>
</div>
<script>
function offsetFromParent(greenId, parentId) {
var green = document.getElementById(greenId);
var parent = document.getElementById(parentId);
return green.getBoundingClientRect().top - parent.getBoundingClientRect().top;
}
test(function() {
assert_equals(offsetFromParent('t1', 't1-cb'), 100);
}, 'abspos containing block, height: 100%, child top: 50%');
test(function() {
assert_equals(offsetFromParent('t2', 't2-cb'), 50);
}, 'abspos containing block, height: 50%, child top: 50%');
test(function() {
assert_equals(offsetFromParent('t3', 't3-cb'), 100);
}, 'abspos containing block, height: stretch, child top: 50%');
test(function() {
assert_equals(offsetFromParent('t4', 't4-cb'), 100);
}, 'abspos containing block, height: calc(100% - 0px), child top: 50%');
test(function() {
assert_equals(offsetFromParent('t5', 't5-cb'), 75);
}, 'abspos containing block, height: calc(50% + 50px), child top: 50%');
test(function() {
assert_equals(offsetFromParent('t6', 't6-cb'), 100);
}, 'abspos containing block, height: 100%, display: inline, child top: 50%');
test(function() {
assert_equals(offsetFromParent('t7', 't7-cb'), 100);
}, 'abspos containing block, height: 100%, display: inline-block, child top: 50%');
test(function() {
assert_equals(offsetFromParent('t8', 't8-cb'), 10);
}, 'abspos containing block in auto-height ancestor, height: 100%, child top: 50%');
test(function() {
assert_equals(offsetFromParent('t9', 't9-cb'), 20);
}, 'abspos containing block in auto-height ancestor, height: 100%, display: inline, child top: 100%');
test(function() {
assert_equals(offsetFromParent('t10', 't10-cb'), 100);
}, 'Nested abspos containing blocks, child top: 50%');
test(function() {
assert_equals(offsetFromParent('t11', 't11-cb'), 50);
}, 'abspos containing block inside abspos with fixed height, child top: 50%');
test(function() {
assert_equals(offsetFromParent('t12', 't12-cb'), 50);
}, 'abspos containing block in percentage chain, child top: 50%');
test(function() {
assert_equals(offsetFromParent('t13', 't13-cb'), 0);
}, 'abspos containing block with top: 0 only (auto height), child top: 50%');
test(function() {
assert_equals(offsetFromParent('t14', 't14-cb'), 0);
}, 'abspos containing block with min-height: 100% only (auto height), child top: 50%');
test(function() {
assert_equals(offsetFromParent('t15', 't15-cb'), 0);
}, 'abspos containing block with all-auto sizing, child top: 50%');
test(function() {
assert_equals(offsetFromParent('t16', 't16-cb'), -100);
}, 'abspos containing block, height: 100%, child bottom: 50%');
test(function() {
assert_equals(offsetFromParent('t17', 't17-cb'), -50);
}, 'abspos containing block, height: 50%, child bottom: 50%');
test(function() {
assert_equals(offsetFromParent('t18', 't18-cb'), -100);
}, 'abspos containing block, height: stretch, child bottom: 50%');
</script>