You can sort of work around this limitation. If you know the absolutely positioned parent's computed position values you can use those combined with calc()
to determine the child's required positioning values relative to the parent that would simulate it being positioned relative to the page. There are a lot of caveats with this solution, so it may not help you.
Scenario 1
We want to position the child using left
as if it's positioned relative to the page. The parent is also positioned using left
.
We can just subtract its left
value from the desired page-relative left
value to get the correct left
value for the child.
var abs2 = document.querySelector('.abs2');
abs2.addEventListener('click', displayPositionValues);
function displayPositionValues() {
var top = abs2.getBoundingClientRect().top;
var left = abs2.getBoundingClientRect().left;
alert('I\'m ' + top + 'px from the top and ' + left + 'px from the left of the page')
}
html, body {
margin: 0;
padding: 0;
}
.normal {
width: 100%;
height: 200px;
background-color: orange;
}
.abs1 {
position: absolute;
top: 40px;
left: 20px;
width: 150px;
height: 150px;
background-color: green;
}
/* we want this to be positioned 100px from the top and 180px from the left of the page */
.abs2 {
position: absolute;
top: calc(100px - 40px); /* top value = page relative top value - parent's top value */
left: calc(180px - 20px); /* left value = page relative left value - parent's left value */
width: 100px;
height: 100px;
font-size: 12px;
text-align: center;
background-color: red;
cursor: pointer;
}
<div class="normal">
<div class="abs1">
<div class="abs2">
Click to display my position values
</div>
</div>
</div>
Scenario 2
We want to position the child using left
as if it's positioned relative to the page. The parent is positioned using right
.
If the page's width equals the viewport's width AND we know the parent's width, then we can determine the child's right
value that corresponds to an equivalent left
value using this formula:
right value = viewport width - desired left value - child's width -
parent's right value
var abs2 = document.querySelector('.abs2');
abs2.addEventListener('click', displayPositionValues);
function displayPositionValues() {
var top = abs2.getBoundingClientRect().top;
var left = abs2.getBoundingClientRect().left;
alert('I\'m ' + top + 'px from the top and ' + left + 'px from the left of the page')
}
html, body {
margin: 0;
padding: 0;
}
.normal {
width: 100%;
height: 200px;
background-color: orange;
}
.abs1 {
position: absolute;
top: 40px;
right: 20px;
width: 150px;
height: 150px;
background-color: green;
}
/* we want this to be positioned 100px from the top and 180px from the left of the page */
.abs2 {
position: absolute;
top: calc(100px - 40px); /* top value = page relative top value - parent's top value */
right: calc(100vw - 180px - 100px - 20px); /* right value = viewport width - desired left value - child's width - parent's right value */
width: 100px;
height: 100px;
font-size: 12px;
text-align: center;
background-color: red;
cursor: pointer;
}
<div class="normal">
<div class="abs1">
<div class="abs2">
Click to display my position values
</div>
</div>
</div>