Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to absolute positioning that updates parents height

I am working on a library that draws brackets.

I am calculating the coordinates of each element (matches and lines) using javascript. Each element has position: absolute; and uses left and top to set their x and y coordinates.

Because I am using position: absolute; it is necessary to set the parent to position: relative; so that the children are positioned relative to their parent.

enter image description here

This was working perfectly until I noticed that the parents height was not updating from its children, because position: absolute; elements are taken out of the flow of the document.

I need the parent to have height so that I can place other elements underneath, and give the parent styles such as background-color...

  1. Is there an alternative to absolute positioning that uses x and y coordinates but also keeps them in the flow of the document to allow the parents width and height to adjust automatically?

  2. Or, if that is not possible, is there away using vanilla javascript (no jQuery or other libraries) to find out the width and height of the contents of the parent div. If this is possible I can just set the parent's width and height styles through javascript.

What I've tried so far

  1. I tried to set the children to position: relative; instead of position: absolute; which I believe would work if you only have one child. However, with more than one child, the children are not relative to the parent but are now relative to the previous child which messes things up.

enter image description here

  1. Even though the parent has no height there is still a vertical scrollbar on the page. Using javascript, I tried to get the scrollHeight and height of elements such as document, document.body and window. This did not work because either the result was undefined or the result was incorrect.

Right now my temporary solution is to set body height to 2500px which should be the highest it will ever need to be. The problem with this is that there will always be a scrollbar, most of the time scrolling to nothing.

Code

<div class="BrackChart_wrapper">
    <div class="BrackChart_match"> ... </div>
    <div class="BrackChart_line"></div>
    etc.
</div>

.BrackChart_wrapper {
    position: relative;
    top: 0px;
    left: 0px;
}

.BrackChart_match, .BrackChart_line {
    position: absolute;
}

Thank you for the help, much appreciated!

JSFiddle: https://jsfiddle.net/jmjcocq8/1/

Solution: https://jsfiddle.net/jmjcocq8/2/

like image 480
David Callanan Avatar asked Oct 30 '22 04:10

David Callanan


1 Answers

I'm fairly sure there's no alternative that both lets you position the children absolutely (relative to their parent) and keeps them in the flow such that they contribute to the size of the parent.

But since you're calculating the positions of the elements yourself, and you know how tall they are, you can set the height of the parent based on the lowest child's y plus height.

You haven't shown your code, but for instance:

var forEach = Array.prototype.forEach;
function positionChildren(parent) {
  var left = 0;
  var top = 0;
  forEach.call(parent.children, function(child, index) {
    child.style.left = left + "px";
    child.style.top = top + "px";
    left += 20;
    top += 10;
  });
  var height = top - 10 + 1 + parent.lastElementChild.clientHeight;
  console.log("height = " + height);
  parent.style.height = height + "px";
}

positionChildren(document.getElementById("parent"));
#parent {
  border: 1px solid black;
  background-color: #ddd;
  position: relative;
}
.child {
  position: absolute;
  border: 1px solid blue;
  padding: 0;
  margin: 0;
}
<div id="parent">
  <div class="child">Child1</div>
  <div class="child">Child2</div>
  <div class="child">Child3</div>
</div>
like image 174
T.J. Crowder Avatar answered Nov 11 '22 10:11

T.J. Crowder