为什么flex-direction:列会删除flex:1的效果?

时间:2019-09-25 15:30:34

标签: html css flexbox

我正在创建带有固定标题的列表视图,并且希望列表视图的主体延伸到页面底部,并且仍然允许y轴上的溢出。在实际运行中,除了在将其放入页面之前没有尝试将其扩展到页面底部的想法之外,我都能使所有功能正常运行。在此之前,我使用固定高度,并且一切都按预期进行。一旦将其放入页面中,列表视图便会远远超出页面的范围,而不是延伸到页面底部并在正文中溢出,而是导致页面溢出。

现在,我已经对该主题进行了一些研究,并且在我的Web样式中的其他地方成功实现了flexbox解决方案几次。但是,事实证明这有点麻烦,我不确定我是否完全掌握了这种方法的概念。

我设法创建了一个最小的问题示例,在此过程中,我设法弄清了CSSflex-direction: column中引起问题的一行在.container中类。当我删除此行时,列表视图仅扩展到页面底部,并且溢出发生在列表视图内。但是,将其重新添加将导致列表视图扩展页面。

var testTable = document.getElementById("test-table");
for (let i = 0; i < 150; i++)
  testTable.innerHTML += '<tr><td>DATA ' + (i + 1) + '</td><td>' + i + '</td></tr>';
html,
body {
  margin: 0;
  height: 100%;
  background-color: #fc3;
  background-image: linear-gradient(45deg, #fc3, #f33);
}

.container {
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  height: 100%;
}

.test-header {
  height: 150px;
  background-color: #fff3;
}

.test-body {
  display: flex;
  flex-direction: column;
  background-color: #33f5;
}

.test-body table {
  width: 100%;
  table-layout: fixed;
}

.test-body-header {
  background-color: #fff5;
}

.test-body-body {
  flex: 1;
  overflow-y: auto;
}
<div class="container">
  <div class="test-header">A</div>
  <div class="test-body">
    <div class="test-body-header">
      <table>
        <tr>
          <th>Data ID</th>
          <th>Value</th>
        </tr>
      </table>
    </div>
    <div class="test-body-body">
      <table id="test-table"></table>
    </div>
  </div>
</div>

我添加了一些JavaScript以减少重现该问题所需的标记量。


为什么在我的flex-direction: column类中添加.container会导致这种不良后果?另外,由于我已经将.test-header类的高度显式设置为150px,所以为什么不显示该高度?这两种效应相关吗?

2 个答案:

答案 0 :(得分:1)

要允许flex子级滚动,您需要在父级上设置overflow:hidden,否则溢出仍然可见,并且子级不会介意身高的父级。

您的CSS再访

var testTable = document.getElementById("test-table");
for (let i = 0; i < 150; i++)
  testTable.innerHTML += '<tr><td>DATA ' + (i + 1) + '</td><td>' + i + '</td></tr>';
html,
body {
  margin: 0;
  height: 100%;
  background-color: #fc3;
  background-image: linear-gradient(45deg, #fc3, #f33);
}

.container {
  display: flex;
  flex-direction: column;
  height: 100%;
  /* overflow rule unnecessary yet here */
}

.test-header {
  height: /*1*/50px;/* down to fifty for the small snippet it stands along*/
  background-color: #fff3;
}

.test-body {
  flex: 1;/* tel it to use all free space */
  overflow: hidden;/* only free space, no more */
  display: flex;
  flex-direction: column;
  background-color: #33f5;
}

.test-body table {
  width: 100%;
  table-layout: fixed;
}

.test-body-header {
  background-color: #fff5;
}

.test-body-body {
  flex: 1;
  overflow: auto;/* let me scroll */
}
<div class="container">
  <div class="test-header">A</div>
  <div class="test-body">
    <div class="test-body-header">
      <table>
        <tr>
          <th>Data ID</th>
          <th>Value</th>
        </tr>
      </table>
    </div>
    <div class="test-body-body">
      <table id="test-table"></table>
    </div>
  </div>
</div>

答案 1 :(得分:1)

只需做两个小调整就可以完成。

1。标头问题

  

由于我已经将.test-header类的高度明确设置为150px,所以为什么不显示该高度?

您的标头(.test-header)不遵循150px,因为flex-shrink的默认设置为1(启用)。这意味着flex项可以缩小到其初始大小以下,以防止容器溢出。

因为它的同级(.test-body)占用了容器中的所有剩余高度,然后,更多的标题将尽可能缩小。

您需要禁用flex-shrink

代替此:

.test-header {
   height: 150px;
 }

尝试一下:

.test-header {
   height: 150px;
   flex-shrink: 0;
 }

或者更好,并且按照规范的建议,这是

.test-header {
   flex: 0 0 150px; /* fg, fs, fb */
 }
  

7.2. Components of Flexibility

     

鼓励作者使用flex速记来控制灵活性   而不是直接使用其速记属性(如速记)   正确重置所有未指定的组件以容纳common uses


2。滚动问题

  

为什么将flex-direction: column添加到我的.container类中会导致这种不良后果?

弹性项目默认情况下不能小于其沿主轴的内容,主轴在flex-direction: columnfull explanation)中是垂直的。

这意味着您的内容元素(.test-body)设置为min-height: auto,这可以防止出现溢出情况,因为该元素只是扩展以容纳更多内容,而不会出现垂直滚动条的情况

您需要覆盖此设置。将此添加到您的代码中:

.test-body {
  min-height: 0; /* new */
  display: flex;
  flex-direction: column;
}

var testTable = document.getElementById("test-table");
for (let i = 0; i < 150; i++)
  testTable.innerHTML += '<tr><td>DATA ' + (i + 1) + '</td><td>' + i + '</td></tr>';
.container {
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  height: 100vh;
}

.test-header {
  flex: 0 0 150px; /* adjustment */
  background-color: #fff3;
}

.test-body {
  min-height: 0; /* new */
  display: flex;
  flex-direction: column;
  background-color: #33f5;
}

.test-body table {
  width: 100%;
  table-layout: fixed;
}

.test-body-header {
  background-color: #fff5;
}

.test-body-body {
  flex: 1;
  overflow-y: auto;
}

body {
  margin: 0;
  background-color: #fc3;
  background-image: linear-gradient(45deg, #fc3, #f33);
}
<div class="container">
  <div class="test-header">A</div>
  <div class="test-body">
    <div class="test-body-header">
      <table>
        <tr>
          <th>Data ID</th>
          <th>Value</th>
        </tr>
      </table>
    </div>
    <div class="test-body-body">
      <table id="test-table"></table>
    </div>
  </div>
</div>