html – 具有两个相等高度子项的Flexbox布局,其中一个包含具有滚动内容的嵌套Flexbox

我有一个< img>右侧的面板包含控件标题和一长串项目.所以我有一个嵌套的flexbox情况:

.container (flex)
 -> .child img
 -> .child controls panel (flex)
  -> .controls
  -> .content-wrapper scrolling list

在一个非常基本的层面上,两个并排面板很容易,是一个简单的弯曲与对齐项目:拉伸.. https://codepen.io/neekfenwick/pen/MOxYxz

在那个基础水平上,它是How do I keep two divs that are side by side the same height?的重复问题.

一旦右侧的面板与垂直滚动列表变得更加复杂,我无法看到如何使其父级的高度,第二个.child,匹配第一个.child的高度. https://codepen.io/neekfenwick/pen/XzGJGw

+-------------+---------------+
|             |  Controls     |
| Left child  |               |
|             +---------------+
|             |              A|
|             | Vertically   |+
|             | scrolling    ||
|             | items        ||
|             |              |+
|             |              V|
+-------------+---------------+

我已经阅读了Flexbox item with scrollable content,但它解决了水平滚动问题,而不是像这样的垂直布局.此外,Nested flexbox with scrolling area处理垂直堆叠的嵌套Flexbox,我认为行和列方向的这种组合混淆了我的情况.

作为代码段:

.container {
  display: flex;
  align-items: stretch;
}

.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>

我不想在这里修复任何元素的高度.碰巧,我知道img的高度,所以我可以使用CSS来强制右边元素的高度,但我想知道是否有一个’真正’的flexbox方法来解决这个问题.

最佳答案
通常,对于溢出:滚动(或自动和隐藏)工作,需要以一种方式或另一种方式高度约束,否则元素通常会根据需要增长以适应其内容.

主要有3种方式,其中要么设置实际高度,要么在第一个样本中,我将其添加到容器中.

堆栈代码段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>

或者使用绝对定位来创建绝对元素所做的高度约束.

它只需使用额外的包装器,内容滚动即可完成,并使结构的其余部分保持完全动态.

堆栈代码段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>

单独使用Flexbox,认为它可能无法完全跨浏览器工作,特别是对于旧版本,仍然支持它但是很麻烦.

原始代码中的简单修复是更改flex:1 1 auto;在.content-wrapper中flex:1 1 0px; (对于我的IE版本需要0px,对于Chrome / Firefox / Edge,可以使用0)

堆栈代码段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>

代码段2和3也回答了您的问题

…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.

注意,如果右列中的顶部元素可以比左列更大,则底部元素上需要最小高度,以防止它崩溃为0,例如,

.content-wrapper {
  ...
  min-height: 200px;           /*  e.g. like this  */
}

转载注明原文:html – 具有两个相等高度子项的Flexbox布局,其中一个包含具有滚动内容的嵌套Flexbox - 代码日志