Overflow Report
by Kenneth Luplau-Brøgger
HTML
<div class="outer">
<div class="inner">
<button>
Trigger
</button>
<div class="test">
Hey
</div>
</div>
</div>
<div id="result"></div>
CSS
.outer {
position: relative;
width: 500px;
height: 500px;
background: yellow;
overflow: hidden;
}
.inner {
position: absolute;
width: 500px;
height: 500px;
background: blue;
}
.test {
position: absolute;
top: 500px;
width: 400px;
height: 100px;
background: black;
color: #fff;
}
JavaScript
const $element = document.querySelector(".test");
const $result = document.querySelector("#result");
const $trigger = document.querySelector("button");
const getRect = (element) => element.getBoundingClientRect();
const isOverflowingParents = ($element, $parent) => {
const rect1 = getRect($element);
const rect2 = getRect($parent);
const {
overflow
} = window.getComputedStyle($parent);
// Is parent overflowing hidden
if (overflow !== "visible") {
const overlapping = {
top: (rect1.top - rect2.top).toFixed(4),
bottom: (rect2.bottom - rect1.bottom).toFixed(4),
left: (rect1.left - rect2.left).toFixed(4),
right: (rect2.right - rect1.right).toFixed(4)
};
// Return first overlapping encounter
if (Object.keys(overlapping).map((direction) => overlapping[direction]).filter((overlaps) => overlaps < 0).length > 0) {
return overlapping;
}
}
// Check grand parent recursive
if ($parent.parentElement) {
return isOverflowingParents($element, $parent.parentElement);
}
// Return false if no overlapping or parents
return false;
}
function mapObject(object, fn) {
return fn(object)
}
const getSafePosition = ($element, $parent, $trigger) => {
const overflows = isOverflowingParents($element, $element.parentElement);
if (overflows) {
const {
top,
right,
bottom,
left
} = overflows;
if (top && bottom > $element.offsetHeight) {
return "bottom";
}
if (right && left > $element.offsetWidth) {
return "left";
}
if (bottom && top > $element.offsetHeight) {
return "top";
}
if (left && right > $element.offsetWidth) {
return "right";
}
return false;
}
}
$result.innerHTML = JSON.stringify(getSafePosition($element, $element.parentElement));