Search code examples
htmlcssflexboxalignment

Flex item won't shrink with overflow - it still remains as high as content


I want one of the children of the display: flex; to adjust the height to the others. If the content in this children is bigger than the other children's, then overflow: scroll; should be done to this content.

In other words: I expect the middle div (yellow background) from the following code to adjust its height to the others div's with overflow of .tabl.

I know that the question is like many others. I have already read many threads and I still have not managed to solve the problem. I apologize for this post, but I do not have the strength to solve it.

.parent {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: baseline;
}

.child1 {
  background-color: red;
  align-self: stretch;
  width: 25%;
  min-width: 25%;
  max-width: 25%;
}

.child2 {
  background-color: yellow;
  min-height: 0;
  min-width: 0;
  overflow: auto;
  margin: 0 15px;
  width: calc(50% - 30px);
  max-width: calc(50% - 30px);
  display: flex;
  flex-direction: column;
  flex-shrink: 1;
}

.child3 {
  background-color: green;
  width: 25%;
  min-width: 25%;
  max-width: 25%;
}

.child2 .tabl {
  flex-shrink: 1;
  min-height: 0;
  overflow: scroll;
}
<div class="parent">
  <div class="child1">
    <p>Some element one</p>
    <p>Some element two</p>
    <p>Some element three</p>
    <p>Some element four</p>
  </div>
  
  <div class="child2">
    <div class="info">
      <h2>Element</h2>
    </div>
    <div class="tabl">
      <p>Some element one</p>
      <p>Some element two</p>
      <p>Some element three</p>
      <p>Some element four</p>
      <p>Some element one</p>
      <p>Some element two</p>
      <p>Some element three</p>
      <p>Some element four</p>
      <p>Some element one</p>
      <p>Some element two</p>
      <p>Some element three</p>
      <p>Some element four</p>
      <p>Some element one</p>
      <p>Some element two</p>
      <p>Some element three</p>
      <p>Some element four</p>
    </div>
    <div class="footer">
      <button class="btn">Some button</button>
    </div>
  </div>
  
  <div class="child3">
      <p>Some element one</p>
      <p>Some element two</p>
      <p>Some element three</p>
      <p>Some element four</p>
      <p>Some element one</p>
      <p>Some element two</p>
      <p>Some element three</p>
      <p>Some element four</p>
  </div>
</div>


Solution

  • I want one of the children of the display: flex; to adjust the height to the others.

    Suppose you want the green section (child3) to have the largest height:

    • make sure you have align-items: stretch (its the default, so don't override it) - this ensures that each row flex child stretches to the maximum height flex child.
    • wrap the contents of the other sections (child1 and child2) into an absolutely positioned element.
    • make this wrapper element a column flexbox to get the overflow right on the yellow section.

    See demo below:

    .parent {
      display: flex;
      flex-direction: row;
      flex-wrap: nowrap;
      /*align-items: baseline;*/
    }
    
    .child1 {
      background-color: red;
      align-self: stretch;
      width: 25%;
      min-width: 25%;
      max-width: 25%;
    }
    
    .child2 {
      background-color: yellow;
      min-height: 0;
      min-width: 0;
      overflow: auto;
      margin: 0 15px;
      width: calc(50% - 30px);
      max-width: calc(50% - 30px);
      display: flex;
      flex-direction: column;
      flex-shrink: 1;
    }
    
    .child3 {
      background-color: green;
      width: 25%;
      min-width: 25%;
      max-width: 25%;
    }
    
    .child2 .tabl {
      flex-shrink: 1;
      min-height: 0;
      overflow: auto; /* changed to auto */
    }
    
    .child1, .child2, .child3 { /* ADDED */
      position: relative;
    }
    
    .child-wrap { /* ADDED */
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
    }
    <div class="parent">
      <div class="child1">
      <div class="child-wrap">
        <p>Some element one</p>
        <p>Some element two</p>
        <p>Some element three</p>
        <p>Some element four</p></div>
      </div>
      
      <div class="child2">
      <div class="child-wrap">
        <div class="info">
          <h2>Element</h2>
        </div>
        <div class="tabl">
          <p>Some element one</p>
          <p>Some element two</p>
          <p>Some element three</p>
          <p>Some element four</p>
          <p>Some element one</p>
          <p>Some element two</p>
          <p>Some element three</p>
          <p>Some element four</p>
          <p>Some element one</p>
          <p>Some element two</p>
          <p>Some element three</p>
          <p>Some element four</p>
          <p>Some element one</p>
          <p>Some element two</p>
          <p>Some element three</p>
          <p>Some element four</p>
        </div>
        <div class="footer">
          <button class="btn">Some button</button>
        </div>
        </div>
      </div>
      
      <div class="child3">
          <p>Some element one</p>
          <p>Some element two</p>
          <p>Some element three</p>
          <p>Some element four</p>
          <p>Some element one</p>
          <p>Some element two</p>
          <p>Some element three</p>
          <p>Some element four</p>
      </div>
    </div>


    Suppose you want either of the left or right sections to have the maximum height - in that case use the above absolute positioning only for the middle yellow element - see demo below where the highest of the left or right elements define the height of the whole parent wrapper :

    .parent {
      display: flex;
      flex-direction: row;
      flex-wrap: nowrap;
      /*align-items: baseline;*/
    }
    
    .child1 {
      background-color: red;
      align-self: stretch;
      width: 25%;
      min-width: 25%;
      max-width: 25%;
    }
    
    .child2 {
      background-color: yellow;
      min-height: 0;
      min-width: 0;
      overflow: auto;
      margin: 0 15px;
      width: calc(50% - 30px);
      max-width: calc(50% - 30px);
      display: flex;
      flex-direction: column;
      flex-shrink: 1;
    }
    
    .child3 {
      background-color: green;
      width: 25%;
      min-width: 25%;
      max-width: 25%;
    }
    
    .child2 .tabl {
      flex-shrink: 1;
      min-height: 0;
      overflow: auto; /* changed to auto */
    }
    
    .child1, .child2, .child3 { /* ADDED */
      position: relative;
    }
    
    .child-wrap { /* ADDED */
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
    }
    <div class="parent">
      <div class="child1">
        <p>Some element one</p>
        <p>Some element two</p>
        <p>Some element three</p>
        <p>Some element four</p>
        <p>Some element two</p>
        <p>Some element three</p>
        <p>Some element four</p>
      </div>
    
      <div class="child2">
        <div class="child-wrap">
          <div class="info">
            <h2>Element</h2>
          </div>
          <div class="tabl">
            <p>Some element one</p>
            <p>Some element two</p>
            <p>Some element three</p>
            <p>Some element four</p>
            <p>Some element one</p>
            <p>Some element two</p>
            <p>Some element three</p>
            <p>Some element four</p>
            <p>Some element one</p>
            <p>Some element two</p>
            <p>Some element three</p>
            <p>Some element four</p>
            <p>Some element one</p>
            <p>Some element two</p>
            <p>Some element three</p>
            <p>Some element four</p>
          </div>
          <div class="footer">
            <button class="btn">Some button</button>
          </div>
        </div>
      </div>
    
      <div class="child3">
        <p>Some element one</p>
        <p>Some element two</p>
        <p>Some element three</p>
    
      </div>
    </div>