如何将滚动添加到弹性项目的子项?

Posted

技术标签:

【中文标题】如何将滚动添加到弹性项目的子项?【英文标题】:How to add scroll to child of flex item? 【发布时间】:2017-03-29 12:03:09 【问题描述】:

使用具有固定高度的 flex 容器,我可以通过设置 overflow: auto 使 flex 项可滚动,如下所示:

page 
  display: flex;
  flex-flow: row wrap;
  height: 200px;

left-panel 
  flex: 1;
  display: block;
  background: lightblue;

//main flex: 5; display: block;
header 
  background: turquoise;
  display: block

//main-content-wrapper flex: 4; display:flex; flex-direction: column
right-panel 
  flex: 1;
  overflow: auto;

content-panel 
  background: pink;
  display: block;

content 
  height: 1000px;
  display: block;
<page>
  <left-panel>left-panel
    <br/>(static)</left-panel>
  <right-panel>
    <header>
      header
      <br/>(static)
    </header>
    <content-panel>
      <content>
        content
        <br/>(scrolls)
      </content>
    </content-panel>
  </right-panel>
</page>

fiddle

但我想让弹性项目的子项滚动。

我认为在 flex 项目上设置 height: 100% 并在我要滚动的子元素上设置 overflow: auto 会起作用,但它不起作用:

page 
  display: flex;
  flex-flow: row wrap;
  height: 200px;

left-panel 
  flex: 1;
  display: block;
  background: lightblue;

//main flex: 5; display: block;
header 
  background: turquoise;
  display: block

//main-content-wrapper flex: 4; display:flex; flex-direction: column
right-panel 
  flex: 1;
  height: 100%;

content-panel 
  background: pink;
  display: block;
  overflow: auto;

content 
  height: 1000px;
  display: block;
<page>
  <left-panel>left-panel
    <br/>(static)</left-panel>
  <right-panel>
    <header>
      header
      <br/>(static)
    </header>
    <content-panel>
      <content>content
        <br/>(scrolls)</content>
    </content-panel>
  </right-panel>
</page>

fiddle

我怎样才能做到这一点?

为什么第二把小提琴不起作用?

添加了 OP cmets:

我可以看到有几个相关的问题,但我发现的问题要么不直接适用,要么提到可能已经修复的错误的解决方法。

我想避免使用显式高度计算来减少组件的耦合。

我可以使用flex-direction: column 将右侧面板转换为嵌套的弹性框,但我希望避免这种情况。

如果没有明确的高度计算就无法实现扁平结构(如第二把小提琴),最好解释一下原因。会不会被认为是 flexbox 的错误,还是我误解了 CSS 的一些基本原理?

【问题讨论】:

【参考方案1】:

如果您将overflow: auto 应用于一个元素以便它可以启动一个垂直滚动条,那么还要给它一个高度限制。

在这种情况下,您只需将height: 100% 添加到要使其可滚动的元素即可。

content-panel 
  background: pink;
  display: block;
  overflow: auto;
  height: 100%; /* NEW */

当然,您需要调整实际百分比值以减去页眉的高度。也许是这样的:

height: calc(100% - 80px)

或者,也许是更好的方法(并且与您添加的拒绝固定高度的 cmets 一致),只需将 right-panel 设为列方向弹性容器:

page 
  display: flex;
  flex-flow: row wrap;
  height: 200px;

left-panel 
  flex: 1;
  display: block;
  background: lightblue;

header 
  background: turquoise;
  display: block

right-panel 
  flex: 1;
  height: 100%;
  display: flex;          /* NEW */
  flex-direction: column; /* NEW */

content-panel 
  background: pink;
  overflow: auto;

content 
  height: 1000px;
  display: block;
<page>
  <left-panel>left-panel
    <br/> (static)</left-panel>
  <right-panel>
    <header>
      header
      <br/>(static)
    </header>
    <content-panel>
      <content>content
        <br/>(scrolls)</content>
    </content-panel>
  </right-panel>
</page>

编辑(基于修改后的问题)

关于overflow 属性:

overflow属性指定是否剪辑内容、渲染 滚动条或仅在溢出其块级别时显示内容 容器。

为了使overflow 属性生效,该块 级别容器必须具有边界高度(heightmax-height) 或将 white-space 设置为 nowrap

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

【讨论】:

感谢您的回答。我确实尝试了这两种方法,但认为应该有一种更清洁的方法。 @1) 避免显式计算孩子的高度是我使用 flexbox 的主要动机。 @2) 这行得通,但似乎有点笨拙,因为我认为这很容易。 第二种方法不需要固定高度。只使用 flex 属性。 是的。我在之前的评论中试图用“@2)”来解决这个问题。 现在清楚了吗,还是您还在寻找更简单的解决方案? 使右侧面板成为一个 flex 容器对我来说似乎非常干净和简单。通过允许您使用 flex 属性,它还为您提供了极大的灵活性。我想不出任何更容易、更简单或更自然的事情了。 Flex 布局就是为这类事情而设计的。【参考方案2】:

将您的right-panel 设为flexbox 列并将flex:1 添加到content-panel - 请参见下面的演示:

page 
  display: flex;
  flex-flow: row wrap;
  height: 200px;

left-panel 
  flex: 1;
  display:block;
  background: lightblue;

header 
  background: turquoise;
  display:block;

right-panel 
  flex: 1;
  display: flex;/*Added this*/
  flex-direction: column;/*Added this*/
  height: 100%;

content-panel 
  background: pink;
  display:block;
  overflow: auto;
  flex:1; /*Added this*/

content 
  display: block;
  height: 1000px;
<page>
  <left-panel>left-panel
    <br/>(static)</left-panel>
  <right-panel>
    <header>
      header
      <br/>(static)
    </header>
    <content-panel>
      <content>
        content
        <br/>(scrolls)
        <br/>more content here
        <br/>more content here
        <br/>more content here
        <br/>more content here
        <br/>more content here
        <br/>more content here
        <br/>more content here
        <br/>more content here
        <br/>more content here
      </content>
    </content-panel>
  </right-panel>
</page>

【讨论】:

【参考方案3】:

您的content-panel 已经拥有height 1000px,而您的content 拥有overflow:auto。你唯一错过的是你没有指定content-panelheightcontent-panel height 必须 content height 才能显示滚动条

<content-panel>
    <content>
      content
      </br>(scrolls)
    </content>
</content>

【讨论】:

以上是关于如何将滚动添加到弹性项目的子项?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止弹性项目在没有包装的情况下溢出弹性父项?

当它也是一个弹性容器时,如何防止最后一个弹性项目填充剩余宽度[重复]

在弹性项目上使用边距

防止弹性项目超过父高度并使滚动条工作

CSS弹性盒子布局flex

如何将排序添加到弹簧数据弹性搜索