Russel Riehle
Russel Riehle

Reputation: 267

Variable heights and overflow in flexbox children

I'm stuck in this scenario:

I'm trying to design this structure:

enter image description here

I have a wrap with 100% width and variable height. This wrap is a flexbox with these settings:

.wrap {
    width:100%;
    display:flex;
    flex-direction:row;
    justify-content:space-between;
    align-items:stretch;
    background:black;
}

Inside this wrap I have two boxes (left and right). Like this:

.left {
    width:250px;
    display:flex;
    flex-direction:column;
    justify-content:space-between;
    background:yellow;
}

.right {
    width:calc(100% - 260px);
    display:flex;
    background: blue;
}

.right img {max-width:100%;}

Inside the .left box I have two other boxes with variable heights. Like this:

.left-one {
    width:100%;
    height:100%;
    background:green;
    margin-bottom:10px;
    overflow:auto;
}

.left-two {
    width:100%;
    background:red;
}

 .left-two img {max-width:100%;}

Everything seems to work.. But...

Inside the .right div I'll have a random image that will make the .wrap height grows. Ok.

And inside the .left-two I'll have another image with unknown dimensions that will make it grow!

This is working. OK. The problem is:

The .left-one div will have dynamic content with unknown height too (text). And I'm trying .left-one div fill all the avaiable space (discounting .left-two height after recieve image) and overflow the surplus text.

And this is not working!

Here is a fiddle without the text inside left-one div: https://jsfiddle.net/bson25c1/7/

And here is a fiddle with the text that should be hidden by scrollbar: https://jsfiddle.net/bson25c1/9/

Upvotes: 1

Views: 119

Answers (1)

Michael Benjamin
Michael Benjamin

Reputation: 371193

This is the problem:

.left-one {
    width: 100%;
    height: 100%;      <-- height 100% of what?
    background: green;
    margin-bottom: 10px;
    overflow: auto;
}

Since you haven't defined a height on the parent, the percentage height on the child falls back to auto (content-based), per the spec.

Here are complete explanations:

Once you fix that percentage height issue, the vertical scroll bar works fine.

Instead of height: 100%, try flex: 1 0 1px (short for flex-grow, flex-shrink, flex-basis).

The flex-basis: 1px is used to trigger the scrollbar, which requires some form of fixed length.

In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap.

https://developer.mozilla.org/en-US/docs/Web/CSS/overflow

Then flex-grow: 1 consumes all free space that may be available.

revised fiddle demo

.wrap {
  display: flex;
  justify-content: space-between;
  background: black;
  height: 100vh;
}

.left {
  flex: 0 0 250px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background: yellow;
}

.right {
  flex: 1;
  display: flex;
  background: blue;
}


.left-one {
  flex: 1 0 1px; /* NEW */
  margin-bottom: 10px;
  overflow: auto;
  background: lightgreen;
}

.left-two {
  background: red;
}

.left-two img,
.right img {
  max-width: 100%;
}

body { margin: 0; }
<div class="wrap">
  <div class="left">
    <div class="left-one">
      HELLO<br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br> HELLO
      <br>
    </div>
    <div class="left-two">
      <img src="https://i.imgur.com/pSCepJR.jpg">
    </div>
  </div>
  <div class="right">
    <img src="https://i.imgur.com/8UZG4cr.jpg">
  </div>
</div>

Upvotes: 2

Related Questions