保持flexbox容器和溢出的子元素在100%高度内

4
我有一个包含3个部分的Flexbox容器。想法是每个部分都像手风琴一样展开,但如果其中任何一个部分展开,我需要该部分内容在垂直方向上溢出,只有当它将整个容器推到父容器的100%高度时,才会保持在Flexbox容器的容器的100%高度内。
这是我尝试使用百分比高度的片段。

html, body {
  height: 100%;
  margin: 0;
}

#container {
  width: 100%;
  height: 100%;
  background-color: gray;
  display: flex;
  flex-direction: column;
}

#a {
  flex: 0 1 auto;
}

#b {
  flex: 2 1 auto;
}

#c {
  flex: 0 1 auto;
}

#s2 {
  max-height: 100%;
  overflow: auto;
  background-color: lightblue;
}
<div id="container">
    <div id="a"><div>Section 1</div></div>
    <div id="b">
      <div>Section 2</div>
      <div id="s2">
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
      </div>
    </div>
    <div id="c"><div>Section 3</div></div>
</div>

我希望能够获得类似以下代码片段的内容,但是不需要指定父元素或Flex子项的显式高度。

html, body {
  height: 100%;
  margin: 0;
}

#container {
  width: 100%;
  height: 100%;
  background-color: gray;
  display: flex;
  flex-direction: column;
}

#a {
  flex: 0 1 auto;
}

#b {
  flex: 2 1 auto;
}

#c {
  flex: 0 1 auto;
}

#s2 {
  max-height: 300px;
  overflow: auto;
  background-color: lightblue;
}
<div id="container">
    <div id="a"><div>Section 1</div></div>
    <div id="b">
      <div>Section 2</div>
      <div id="s2">
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
      </div>
    </div>
    <div id="c"><div>Section 3</div></div>
</div>

请注意,第3节填补了第2节推断的flex-basis留下的空缺。我希望第2节能够增长到100%,然后溢出。使用 flexbox 是否可能实现这一点?
我被类似的问题压倒了,其中最接近的是: 如何使div填充剩余屏幕空间的高度 - 这非常相似,但我的问题添加了“如果溢出100%则需要滚动”。 具有max-height:100%的子元素溢出父元素 - 我认为这是问题的根源。如果没有设置父高度,它无法计算要从哪里溢出的高度。 如何使flexbox容器滚动? - 再次需要像素单位的flex-basis。 :(。
我可以使用display:tables或其他解决方案。在输入完毕后,我认为需要一个javascript解决方案。
3个回答

2

请查看此链接

问题在于flexbox中的项具有隐式的“最小高度”,等于其实际高度。您可以设置min-height: 0px

“Original Answer”翻译成“最初的回答”。

html, body {
  height: 100%;
  margin: 0;
}

#container {
  height: 100%;
  background-color: gray;
  display: flex;
  flex-direction: column;
}

#b {
  flex: 100% 1 1;
  min-height: 0px; // this is important!
  overflow: hidden;
  display: flex; // make it a flex too so you have better control of the scrollbar
  flex-direction: column;
}

#s2 {
  min-height: 0px;
  max-height: 100%;
  overflow: auto;
  background-color: lightblue;
}

1
你已经做得很好了。只需将 #b 元素也变成一个 Flexbox 容器,并使用 overflow: hiddenmin-height: 0

html, body {
  height: 100%;
  margin: 0;
}

#container {
  width: 100%;
  height: 100%;
  background-color: gray;
  display: flex;
  flex-direction: column;
}

#a {
  flex: 0 1 auto;
}

#b {
  flex: 2 1 auto;
  overflow:hidden;
  /*added this*/
  display:flex;
  flex-direction:column;
  /**/
}

#c {
  flex: 0 1 auto;
}

#s2 {
  overflow: auto;
  background-color: lightblue;
}
<div id="container">
    <div id="a"><div>Section 1</div></div>
    <div id="b">
      <div>Section 2</div>
      <div id="s2">
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
      </div>
    </div>
    <div id="c"><div>Section 3</div></div>
</div>

如果不将#b设置为弹性盒容器,您也可以考虑在s2上使用height:100%

html, body {
  height: 100%;
  margin: 0;
}

#container {
  width: 100%;
  height: 100%;
  background-color: gray;
  display: flex;
  flex-direction: column;
}

#a {
  flex: 0 1 auto;
}

#b {
  flex: 2 1 auto;
  overflow:hidden;
}

#c {
  flex: 0 1 auto;
}

#s2 {
  height:100%;
  overflow: auto;
  background-color: lightblue;
}
<div id="container">
    <div id="a"><div>Section 1</div></div>
    <div id="b">
      <div>Section 2</div>
      <div id="s2">
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
      </div>
    </div>
    <div id="c"><div>Section 3</div></div>
</div>


1
你的手风琴中的 #b 部分会填充在 #container 中剩余的空间,所以你可以将这个垂直空间分配给它的内容 - 标题和 #s2
  • #b 设为一个具有 flex-direction: column 属性的 Flexbox
  • 同时记得为 #b 设置 min-height: 0(默认情况下,Flex项目min-height 是自动的)
  • #b 中的 flex: 1 就足够了,不需要设为 flex: 2 1 auto
  • 还需要将 #s2 设为 flex: 1,这样它就能在 #b填满剩余空间(你可以去掉 max-height: 100%)。
请查看以下演示:

html, body {
  height: 100%;
  margin: 0;
}

#container {
  width: 100%;
  height: 100%; 
  background-color: gray;
  display: flex;
  flex-direction: column;
}

#a {
  flex: 0 1 auto;
}

#b {
  flex: 1; /* this would do */
  display: flex; /* added*/
  flex-direction: column; /* added */
  min-height: 0; /* added */
}

#c {
  flex: 0 1 auto;
}

#s2 {
  flex: 1; /* added */
  /* max-height: 100%;*/
  overflow: auto;
  background-color: lightblue;
}
<div id="container">
    <div id="a"><div>Section 1</div></div>
    <div id="b">
      <div>Section 2</div>
      <div id="s2">
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
      </div>
    </div>
    <div id="c"><div>Section 3</div></div>
</div>


现在您拥有了全视口手风琴 - 当手风琴项展开时,您还可以让#container仅占用所需空间,并允许其在视口高度处扩展,之后再溢出 - 只需将 container 中的 height:100%更改为 max-height:100% - 请参见下面的演示:

html, body {
  height: 100%;
  margin: 0;
}

#container {
  width: 100%;
  max-height: 100%; /* changed to max-height */
  background-color: gray;
  display: flex;
  flex-direction: column;
}

#a {
  flex: 0 1 auto;
}

#b {
  flex: 1; /* this would do */
  display: flex; /* added*/
  flex-direction: column; /* added */
  min-height: 0; /* added */
}

#c {
  flex: 0 1 auto;
}

#s2 {
  flex: 1; /* added */
  /* max-height: 100%;*/
  overflow: auto;
  background-color: lightblue;
}
<div id="container">
    <div id="a"><div>Section 1</div></div>
    <div id="b">
      <div>Section 2</div>
      <div id="s2">
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
       <div>Item</div>
      </div>
    </div>
    <div id="c"><div>Section 3</div></div>
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接