Flexbox layout with two equal height children, one containing nested flexbox with scrolling content

孤街醉人 提交于 2019-11-28 10:35:36

In general, for overflow: scroll (or auto and hidden) to work, a height constraint is needed in one way or the other, or else element's normally grow as much as needed to fit their content.

There is mainly 3 ways, where either an actual height is set, as in this first sample, where I added it to the container.

Stack snippet 1

.container {
  display: flex;
  height: 100vh;
}

.child {
  border: 1px solid grey;
  background-color: lightgrey;
  flex: 1 1 auto;
}

.controls-panel {
  display: flex;
  flex-direction: column;
}

.controls {
  flex: 0 0 auto;
}

.content-wrapper {
  flex: 1 1 auto;
  width: 400px;
  overflow-y: auto;
}
.content-item {
  display: inline-block;
  width: 100px;
  height: 100px;
  background-color: red;
}
<div class="container">
  <div class="child">
    <p>In real life I am an inline img.</p>
    <p>I am some content whoop de doo.</p>
    <p>I am some content whoop de doo.</p>
    <p>I am some content whoop de doo.</p>
    <p>I want my sibling to equal my height.</p>
  </div>
  <div class="child controls-panel">
    <div class="controls">
      <p>Small controls area. Panel below should scroll vertically.</p>
    </div>
    <div class="content-wrapper">
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
      <div class="content-item"></div>
    </div>
  </div>
</div>

Or to use absolute positioning to create that height constraint, which an absolute element does.

It is simply accomplished with an extra wrapper, content-scroll, and will keep the rest of the structure fully dynamic.

Stack snippet 2

.container {
  display: flex;
}

.child {
  border: 1px solid grey;
  background-color: lightgrey;
  flex: 1 1 auto;
}

.controls-panel {
  display: flex;
  flex-direction: column;
}

.controls {
  flex: 0 0 auto;
}

.content-wrapper {
  position: relative;
  flex: 1 1 auto;
  width: 400px;
}
.content-scroll {
  position: absolute;
  top: 0; left: 0;
  right: 0; bottom: 0;
  overflow-y: auto;
}
.content-item {
  display: inline-block;
  width: 100px;
  height: 100px;
  background-color: red;
}
<div class="container">
  <div class="child">
    <p>In real life I am an inline img.</p>
    <p>I am some content whoop de doo.</p>
    <p>I am some content whoop de doo.</p>
    <p>I am some content whoop de doo.</p>
    <p>I want my sibling to equal my height.</p>
  </div>
  <div class="child controls-panel">
    <div class="controls">
      <p>Small controls area. Panel below should scroll vertically.</p>
    </div>
    <div class="content-wrapper">
      <div class="content-scroll">
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
      </div>
    </div>
  </div>
</div>

Use Flexbox alone, thought it might not work fully cross browsers, especially with older versions, that still support it but is a lot buggier.

The simple fix in your original code is to change the flex: 1 1 auto; in .content-wrapper to flex: 1 1 0px; (0px were needed for my IE version, for Chrome/Firefox/Edge one can use 0)

Stack snippet 3

.container {
  display: flex;
}

.child {
  border: 1px solid grey;
  background-color: lightgrey;
  flex: 1 1 auto;
}

.controls-panel {
  display: flex;
  flex-direction: column;
}

.controls {
  flex: 0 0 auto;
}

.content-wrapper {
  flex: 1 1 0px;
  width: 400px;
  overflow-y: auto;
}
.content-item {
  display: inline-block;
  width: 100px;
  height: 100px;
  background-color: red;
}
<div class="container">
  <div class="child">
    <p>In real life I am an inline img.</p>
    <p>I am some content whoop de doo.</p>
    <p>I am some content whoop de doo.</p>
    <p>I am some content whoop de doo.</p>
    <p>I want my sibling to equal my height.</p>
  </div>
  <div class="child controls-panel">
    <div class="controls">
      <p>Small controls area. Panel below should scroll vertically.</p>
    </div>
    <div class="content-wrapper">
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
        <div class="content-item"></div>
    </div>
  </div>
</div>

Snippet 2 and 3 also answers your question

...with a vertically scrolling list, I cannot see how to make the height of its parent, the second .child, match the height of the first .child.

Note, if the top element in the right column can grow bigger than the left column, a minimum height will be needed on the bottom element, to prevent it from collapse into 0, e.g.

.content-wrapper {
  ...
  min-height: 200px;           /*  e.g. like this  */
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!