1

I have a nested structure of flexbox containers, where an inner container needs to show potentially large content in a scrollable pane. However, sometimes the content is small.

There's an additional container that needs to be always visible, and that I'd like to have just below the scrollable content, i.e. not far down at the bottom unless the scrollable pane content "pushes" it down - the viewport can be much larger than the content.

What I have right now does everything except have the "Right bottom" come up when the "Right top content" is small:

JsFiddle: https://jsfiddle.net/u6dou3wf/10/

JsFiddle output

.main {
  display: flex;
  height: 200px;
}

.left {
  flex: 1 1 0;
  background: red;
}
.right {
  flex: 0 0 0;
  display:flex;
  flex-direction: column;
  background: green;
  padding: 4px;
}

.right-top-wrapper {
  flex: 1 1 0;
  overflow-x: auto;
  overflow-y: scroll;
  background: blue;
}

.right-top-content {
  margin: 4px;
  height:100px;
  width:100px;
  background: pink;
}

.right-bottom {
  flex: 0 0 0;
  background: yellow;
  margin: 4px;
}
<div class="main">
 <div class="left">
 Left content
 </div>
 <div class="right">
  <div class="right-top-wrapper">
   <div class="right-top-content">
    Right top content
   </div>
  </div>
  <div class="right-bottom">
   Right bottom
  </div>
 </div>
</div>

How can I get the "Right bottom" to be snugly below the "Right top content", i.e. get the blue section to shrink if the pink section is small, and then grow to whatever size is available inside the green (minus yellow) if the pink section is large?

I have tried .right-top-wrapper { flex: 0 1 0; } but then it shrinks to nothing (a consequence of overflow-y: scroll or auto, which I have to have to allow large "Right top content").

Jxtps
  • 654
  • 5
  • 15

2 Answers2

1

Okay, After having a quick fiddle, and if i am right in thinking of what you want to achieve, Change your CSS:

.main {
  display: flex;
  height: 200px;
}

.left {
  flex: 1 1 auto;
  background: red;
}
.right {
  flex: 0 1 auto;
  display:flex;
  flex-direction: column;
  background: green;
  padding: 4px;
}

.right-top-wrapper {
  flex: 0 0 auto;
  overflow-x: auto;
  overflow-y: auto;
  background: blue;
}

.right-top-content {
  margin: 4px;
  flex: auto;
  background: pink;
}

.right-bottom {
  flex: 0 0 0;
  background: yellow;
  margin: 4px;
}

If you want the main to be a fixed width, adjust that accordingly too.

Ricky
  • 763
  • 3
  • 7
  • 29
1

Your blue container (.right-top-wrapper) is set to flex: 1 1 0. This breaks down to:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0

It's the flex-grow: 1 that's forcing the element to consume all available space in the column, leaving the content (pink box) behind, and pinning the yellow "Right bottom" box to the bottom.

You wrote:

I have tried .right-top-wrapper { flex: 0 1 0; } but then it shrinks to nothing (a consequence of overflow-y: scroll or auto, which I have to have to allow large "Right top content").

No, it's a consequence of flex-basis: 0, which translates to height: 0. Without flex-grow: 1 to expand the height like before, the box has a zero height.

Try this instead: .right-top-wrapper { flex: 0 1 auto; }

Now flex-grow is disabled and the box takes the height of the content.

You also need to release the fixed height on the pink box so it expands along with the blue container.

.right-top-content { 
     /* height: 100px */ 
     min-height: 100px; /* new */
}

revised fiddle (little content)

revised fiddle (lots of content)

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701