如何在弹性项目上启用滚动条?

时间:2018-01-03 11:00:16

标签: css css3 flexbox

我有一个基于flexbox的布局,其中两个面板(顶部和底部)分别占据视口的1/3和2/3。 (实际上有更多的面板,但我把它简化为最小的例子。)

顶部面板也是一个弹性容器,因为我希望它的孩子从上到下流动,并在有空间时垂直居中。当顶部面板中的东西多于其中的东西时,我希望它可以滚动,因此overflow: auto

问题:top的内容缩小到其大小,即使使用flex-shrink: 0,滚动条也不会弹出。

观察以下演示中content是如何缩小的,即使它具有明确指定的高度:

html, body {
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
}

.main {
    display: flex;
    height: 100%;
    flex-direction: column;
}

.top {
    display: flex;
    flex-direction: column;
    flex-basis: 33%;
    border-bottom: 1px solid #ccc;
    overflow: auto;
    justify-content: center;
    padding: 20px;
}

.bottom {
    overflow: auto;
    flex-basis: 67%;
}

.content {
    height: 500px;
    background-color: #eee;
}
<div class="main">
  <div class="top">
    <div class="content">Content</div>
  </div>
  <div class="bottom"></div>
</div>

问题:

  1. 如何在保留布局要求的同时解决此问题?禁用顶部面板的display: flex可在演示中获得所需的效果。我可以以无flexbox方式定位top的内容,但我失去了flex布局和自动垂直居中的好处。

  2. 为什么会这样?欢迎参考CSS规范。

2 个答案:

答案 0 :(得分:1)

您写道:

  

问题:top的内容缩小到其大小,即使使用flex-shrink: 0,滚动条也不会弹出。

实际上,解决方案是flex-shrink: 0。所以问题就变成了,你在哪里应用它?

如果您将其应用于top - 主容器中的flex-basis: 33%(即height: 33%,在这种情况下)的灵活项目,则无法使用 - 因为top是一个百分比。因此,当百分比长度相对于父容器时,它将自然收缩/扩展。

您需要将flex-shrink: 0应用于.content - 嵌套容器中具有固定高度(height: 500px / flex-basis: 500px)的弹性项目。

所以这会奏效:

.content {
    height: 500px;
    flex-shrink: 0;
}

或者这个:

.content {
    flex-basis: 500px;
    flex-shrink: 0;
}

或者,更好的是,这个:

.content {
    flex: 0 0 500px;  /* don't grow, don't shrink, stay fixed at 500px */
}

来自规范:

  

7.2. Components of Flexibility

     

鼓励作者使用flex简写来控制灵活性   而不是直接用它的速记属性,作为速记   正确地重置任何未指定的组件以容纳common uses

body {
  margin: 0;
}

.main {
  display: flex;
  flex-direction: column;
  height: 100vh;  
}

.top {
  display: flex;
  flex-direction: column;
  flex-basis: 33%;
  border-bottom: 1px solid #ccc;
  overflow: auto;
  justify-content: center;
  padding: 20px;
}

.bottom {
  overflow: auto;
  flex-basis: 67%;
}

.content {
  flex: 0 0 500px;
  background-color: #eee;
}
<div class="main">
  <div class="top">
    <div class="content">Content</div>
  </div>
  <div class="bottom"></div>
</div>

然后你有第二个问题,即top元素的上半部分被切断并且无法通过滚动访问。这是由容器上的justify-content: center引起的。

这是一个已知问题。它通过使用flex auto边距来解决。

所以不要这样:

.top {
    display: flex;
    flex-direction: column;
    flex-basis: 33%;
    border-bottom: 1px solid #ccc;
    overflow: auto;
    /* justify-content: center;  <--- REMOVE */
    padding: 20px;
}

这样做:

.content {
  flex: 0 0 500px;
  margin: auto 0; /*  top & bottom auto margins */
  background-color: #eee;
}

body {
  margin: 0;
}

.main {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.top {
  display: flex;
  flex-direction: column;
  flex-basis: 33%;
  border-bottom: 1px solid #ccc;
  overflow: auto; 
  /* justify-content: center;  USE AUTO MARGINS ON FLEX ITEM INSTEAD */
  padding: 20px;
}

.bottom {
  overflow: auto;
  flex-basis: 67%;
}

.content {
  flex: 0 0 500px;
  margin: auto 0;
  background-color: #eee;
}
<div class="main">
  <div class="top">
    <div class="content">Content</div>
  </div>
  <div class="bottom"></div>
</div>

以下是完整的解释:

答案 1 :(得分:0)

当有足够的.content元素缩小到非常小的高度(在这种情况下为一行高度)时,会出现滚动条。

这并不是真的如何使用flex。 height并未受到严格尊重。如果您仍想使用height,则可以根据所需的最低身高将min-height设置为.content来解决此问题。

或者您可以在flex上设置.content(并摆脱height): css flex: 100px 1 0; 这将设置最小高度(flex-basis)为100px,flex-grow为1以便占用所有可用空间,并将flex-shrink设置为0,以便元素始终至少为100px高。