1

The function I want to implement is that a parent element that contains an indefinite number of child elements can automatically extend its height to the furthest point of the children when the total height of the children exceeds the parent's. The parent has a fixed height if the children's total height do not exceed that height. Here's the diagram:

enter image description here

I've tried and searched for hours and still couldn't get it to work. Don't know what's been missing here. Here's a demo snippet and when you click on the blue panel it will exceed the white panel but the white one does not extend accordingly.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <style>
    html,
    body {
      height: 100%;
      background-color: grey;
      margin: 0;
    }
    
    #left-panel {
      position: relative;
      width: 256px;
      height: 100%;
      background-color: white;
    }
    
    #child-panel {
      position: absolute;
      width: 30%;
      height: 40%;
      top: 20%;
      left: 30%;
      background-color: blue;
    }
  </style>
  <script>
    window.onload = init;

    function init() {
      var leftPanel = document.getElementById("left-panel");
      var childPanel = document.getElementById("child-panel");
      childPanel.onclick = function(ev) {
        if (childPanel.offsetHeight < leftPanel.offsetHeight) {
          childPanel.style.height = leftPanel.offsetHeight + 100 + "px";
          leftPanel.style.height = leftPanel.offsetHeight + 100 + "px";
        } else {
          childPanel.style.height = "40%";
          leftPanel.style.height = "100%";
        }
      }
    }
  </script>
</head>

<body>
  <div id="left-panel">
    <div id="child-panel"></div>
  </div>
</body>

</html>
Joseph Tesfaye
  • 814
  • 14
  • 26
  • A single CSS rule should do this: `#left-panel {min-height: SOME_HEIGHTunit;}`. This provides the content should not be pulled out of the textflow, though. – Teemu Dec 28 '18 at 08:29
  • Use min-height:??px and height : auto for the parent – vishulg Dec 28 '18 at 08:29
  • 1
    an absolute positioned div "does not take place" (it's removed out of the flow, cf Teemu's comment) so the parent cannot resize. [One of these answers should solve the problem](https://stackoverflow.com/questions/12070759/make-absolute-positioned-div-expand-parent-div-height) – Kaddath Dec 28 '18 at 08:38

5 Answers5

2

it is simple, you don't need javascript to get the right bhavior

  1. first i used this html and css code that gives the same ui as yours in the pictures :

    <div class="parent-purpel">
    <div class="firstChild-yellow">
    
        <div class="thirdChild-orange">
    
        </div>
    </div>
    

it gives me the result below : enter image description here

then i used flex in the css :

.firstChild-yellow{
background-color: yellow;
width: 30%;
height: auto;
margin : 30px; 
display: flex;    /* <====================== */
flex-direction: column;    /* <======= to get orange squares in vertical align */}

important ! : we have to use an auto height in the yellow and the purpel divs :

.parent-purpel{
background-color: purple;
width: 100%;
height: auto;  /*<===== important*/  }

.firstChild-yellow{
background-color: yellow;
width: 30%;
height: auto; /*<===== important*/
margin : 30px; 
display: flex;
flex-direction: column;}

Now even we add orange elements to the yellow div we will have variable height of the divs yellow and purpel like that : enter image description here i hope that will help you thanks !

here is the full code :

html : test1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="test1.css">
    <title>Document</title>
</head>
<body>
    <div class="parent-purpel">
        <div class="firstChild-yellow">
            <div class="thirdChild-orange">

            </div>
            <div class="thirdChild-orange">    

            </div>
            <div class="thirdChild-orange">

            </div>
            <div class="thirdChild-orange">

            </div>
        </div>
    </div>

</body>
</html>

CSS : test1.css

.parent-purpel{
background-color: purple;
width: 100%;
height: auto;}

.firstChild-yellow{
background-color: yellow;
width: 30%;
height: auto;
margin : 30px; 
display: flex;
flex-direction: column;}

.thirdChild-orange{
background-color: orange;
width: 60%;
height: 200px;
margin: 30px;}
nadir hamidou
  • 423
  • 2
  • 7
  • 18
0

Try this one:

var childTop = childPanel.offsetTop
if (childPanel.offsetHeight < leftPanel.offsetHeight) {
   childPanel.style.height = leftPanel.offsetHeight - childTop + "px";
   leftPanel.style.height = leftPanel.offsetHeight  + "px";
}

you were setting child height (cHeight) as parent height (pHeight) so let's assume


pHeight = 100px;
cheight = pHeight in your case childPanel.style.height = leftPanel.offsetHeight

it means both elements are having the same height but child element also have top: 20%; that you have to reduce from the height of the child.

Calculate Top of the child: var childTop = childPanel.offsetTop

and then reduce from height

childPanel.style.height = leftPanel.offsetHeight - childTop + "px";

Vinesh Goyal
  • 607
  • 5
  • 8
0

Why don't you just try something like;

    <!-- min height will be the height that you want to keep fixed if lesser number of children -->
    <div style="border:1px solid black; padding:5px; min-height:50px"> 
        <div>
          Child 1
        </div>
        <div>
          Child 2
        </div>
        <div>
          Child 3
        </div>
        <div>
          Child 4
        </div>
    </div>
KOUSIK MANDAL
  • 2,002
  • 1
  • 21
  • 46
0

it's the:

#child-panel {
   position: absolute;
}

that is causing the behaviour, to get the position use padding and margin:

#left-panel {
    padding: 5% 2%;
}

#child-panel {
    margin: auto;
}
David Bray
  • 566
  • 1
  • 3
  • 15
0

The key is to use

min-height: 100%;
height: auto;

for parent panel and don't use

position: absolute; 

for the child panels. If you want to re-position the child panels use a wrapper panel instead. Here's the code that when you click on the blue panels the parent and the panels are all extended accordingly.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <style>
        html, body {
            height: 100%;
            background-color: grey;
            margin: 0;
        }

        #left-panel {
            width: 256px;
            min-height: 100%;
            height: auto;
            background-color: white;
        }

        .child-panel-wrapper {
            width: 30%;
            height: auto;
            background-color: yellow;
            position: relative;
            left: 30%;
        }

        .child-panel {
            background-color: blue;
            height: 200px;
        }
    </style>
    <script>
        window.onload = init;
        function init() {
            var childPanels = document.getElementsByClassName("child-panel");
            for (var i = 0; i < childPanels.length; i++) {
                var panel = childPanels[i];
                panel.addEventListener("click", function (evt) {
                    if (this.offsetHeight <= 200) {
                        this.style.height = 600 + "px";
                    } else {
                        this.style.height = 200 + "px";
                    }
                })
            }
        }
    </script>
</head>
<body>
<div id="left-panel">
    <div class="child-panel-wrapper">
        <div class="child-panel"></div><br>
        <div class="child-panel"></div><br>
        <div class="child-panel"></div>
    </div>
</div>
</body>
</html>
Joseph Tesfaye
  • 814
  • 14
  • 26