【问题标题】:Flexbox layout with two equal height children, one containing nested flexbox with scrolling content具有两个等高子级的 Flexbox 布局,一个包含具有滚动内容的嵌套 flexbox
【发布时间】:2018-05-17 14:33:46
【问题描述】:

我有一个<img>,其右侧有一个面板,其中包含一个控件标题和一长串项目。所以我有一个嵌套的弹性盒情况:

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

在非常基本的层面上,两个并排的面板很容易,通过align-items: stretch .. 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 处理垂直堆叠的嵌套弹性盒,我认为rowcolumn 方向的组合让我感到困惑。

作为代码sn-p:

.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 方法来解决这个问题。

【问题讨论】:

  • 我能做些什么来让我的答案被接受吗?
  • 我真的很抱歉耽搁了。您的回答非常好,我现在刚刚被项目的其他部分所淹没。我在您发布它时阅读了它,但是您使用了我以前从未见过的技巧并且需要时间来试验。我会评论答案。
  • 没问题 :) ... 只是在跟进我的回答

标签: html css flexbox overflow


【解决方案1】:

一般来说,要使overflow: scroll(或autohidden)工作,需要以一种或另一种方式限制高度,否则元素通常会根据需要增长以适应其内容。

主要有 3 种方式,可以设置实际高度,如在第一个示例中,我将其添加到 container

堆栈 sn-p 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>

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

只需使用额外的包装器content-scroll 即可完成,并将保持结构的其余部分完全动态。

堆栈 sn-p 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,认为它可能无法完全跨浏览器工作,尤其是旧版本,它仍然支持它,但错误很多。

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

堆栈 sn-p 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 也回答了您的问题

...带有垂直滚动列表,我看不到如何制作 其父级的高度,第二个.child,与 第一个.child

注意,如果右列的顶部元素可以增长到大于左列,则底部元素需要一个最小高度,以防止其塌陷为0,例如

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

【讨论】:

  • 优秀的答案。我测试了 Snippet 2 并发现它确实有效,但是使用 position: absolute 似乎是一个不舒服的黑客。 Snippet 3 似乎是一种更简洁的方法。我以前不明白flex-basisdeveloper.mozilla.org/en-US/docs/Web/CSS/flex-basis 声明“flex-basis CSS 属性指定了 flex 项的初始主大小。除非使用 box-sizing 另有指定,否则此属性确定内容框的大小。”,我是否更正了您的 flex-basis: 0px 设置初始高度为零,然后框扩展以匹配其兄弟?完美!
  • @Neek 是的,flex-basis: 0(或 IE 上的flex-basis: 0px)意味着简单地说它被视为空的,因此它的flex-grow: 1 将填充剩余空间。第三个 sn-p 是 cleaner,虽然第二个有更好的浏览器支持,因为可能有旧的浏览器,仍然支持 Flexbox,这可能不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-29
  • 1970-01-01
  • 1970-01-01
  • 2017-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多