Hassaki - 1 year ago 65
Javascript Question

Calculating height of absolute positioned nested childs

I've stuck at the problem with this

``````.autoHeightParent {
width: 500px; /* just for example */
position: relative;
}
.absolutePosChild {
/* absolute is required to make pretty drag and drop transitions with interpolating left property */
position: absolute;
display:flex;
flex-direction: column;
border: 1px solid green;
}
.absolutePosChild div {
width: 100%;
}``````

``````<div class="autoHeightParent" style="height:170px;">
<div class="absolutePosChild" style="left: 0px; width: 100px;">
<div>
Child content
</div>
</div>
<div class="absolutePosChild" style="left: 100px; width: 150px;">
<div>
Child content with nesting
</div>
<!-- !! NESTING  -->
<div class="autoHeightParent">
<div class="absolutePosChild" style="left: 0px; width: 50px;">
<div>
We don't know this height too
</div>
</div>
<div class="absolutePosChild" style="left: 50px; width: 100px;">
<div>
G.Child 2
</div>
</div>
</div>
</div>
</div>
<div style="border: 1px solid red">
I need to automatcally calculate height of the box above to make THIS box right after it. For now you can see hardcoded 170px height.
</div>``````

How do you guys solve problems like this?

I have tried to solve it with javscript but my solution looks wrong.

``````function setRootHeight() {
var root = document.getElementById("root");
var allChilds = root.getElementsByTagName("*");
var rootRect = root.getBoundingClientRect();
var maxChildHeight = 0;
_.each(allChilds, function(item) {
var nodeRect = item.getBoundingClientRect();
var nodeHeightRelativeToRoot = ( nodeRect.top + nodeRect.height ) - rootRect.top;
if ( nodeHeightRelativeToRoot > maxChildHeight) maxChildHeight = nodeHeightRelativeToRoot;
});
root.style.height = maxChildHeight + "px";
}

setInterval(setRootHeight, 300);``````

``````.autoHeightParent {
width: 500px; /* just for example */
position: relative;
}
.absolutePosChild {
/* absolute is required to make pretty drag and drop transitions with interpolating left property */
position: absolute;
display:flex;
flex-direction: column;
border: 1px solid green;
}
.absolutePosChild div {
width: 100%;
}``````

``````<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.2.1/lodash.min.js"></script>
Test content Above
<div id="root" class="autoHeightParent">
<div class="absolutePosChild" style="left: 0px; width: 100px;">
<div>
Child content
</div>
</div>
<div class="absolutePosChild" style="left: 100px; width: 150px;">
<div>
Child content with nesting
</div>
<!-- !! NESTING  -->
<div class="autoHeightParent">
<div class="absolutePosChild" style="left: 0px; width: 50px;">
<div>
We don't know this height too
</div>
</div>
<div class="absolutePosChild" style="left: 50px; width: 100px;">
<div>
G.Child 2
</div>
</div>
</div>
</div>
</div>
<div style="border: 1px solid red">
Visualization of that height was calculated
</div>``````

It uses setInteval to check if any of nested children changed it's height and then recalculate height of the parent box. Actually i need to find better solution because of performance and code beauty.

Snippets very simplified compared to real recalculations.

I am free to use flexbox or any tool that can solve this

I've solved this issue with relative positioning.

For my complex "absolute position" animations i made function that translates absolute to relative.

For example

``````.autoHeightParent {
width: 500px; /* just for example */
position: relative;
display: flex;
}
.absolutePosChild {
/* relative position here must do absolutes' job here */
position: relative;
display:flex;
flex-direction: column;
border: 1px solid green;
}
.absolutePosChild div {
width: 100%;
}``````
``````<!DOCTYPE html>
<html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<body>
<div class="autoHeightParent">
<div class="absolutePosChild">
<div>
Child content
</div>
</div>
<div class="absolutePosChild">
<div>
Child content with nesting
</div>
<!-- !! NESTING  -->
<div class="autoHeightParent">
<div class="absolutePosChild">
<div>
We don't know this height too
</div>
</div>
<div class="absolutePosChild">
<div>
G.Child 2
</div>
</div>
</div>
</div>
</div>

</body>
</html>``````

You see that parent box automatically resizes fine. But now i can use translate3d to any child and parent box keeps it's size and position.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download