html - 如何使 flexbox 元素的后代元素可滚动?

标签 html css flexbox

我正在使用 flexbox 布局,目的是扩展最后一项以适应可用的屏幕空间。当该元素太大时,我想滚动其中一个后代元素。但是,我无法按预期进行滚动。

示例布局:

var node = document.getElementById("table-body");
for (var i = 0; i < 200; i++) {
  node.innerHTML += '<tr><td>' + i + '</td></tr>';
}
html,
body {
  height: 100%;
  margin: 0px;
}
.flexbox {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}
#grid-selected-container {
  flex-basis: 30%;
  flex-grow: 0;
  flex-shrink: 0;
  align-self: stretch;
}
#grid-available-container {
  flex-grow: 1;
  flex-shrink: 1;
  align-self: stretch;
  height: 100%;
}
<div class="flexbox">
  <div id="grid-selected-container">
    <table width="100%" class="display" id="grid-selected">
      <tr>
        <td>placeholder</td>
      </tr>
    </table>
  </div>
  <button id="button-render" type="button" class="btn btn-default btn-lg">placeholder</button>
  <div id="grid-available-container">
    <div class="scroll-wrapper">
      <div class="fixed-head">
        <table width="100%" class="display">
          <thead>
            <th>header</th>
          </thead>
        </table>
      </div>
      <div class="scroll-body">
        <table width="100%" class="display" id="grid-available">
          <tbody id="table-body">
          </tbody>
        </table>
      </div>
    </div>
  </div>
</div>

我可以滚动整个 flex 元素:

var node = document.getElementById("table-body");
for (var i = 0; i < 200; i++) {
  node.innerHTML += '<tr><td>' + i + '</td></tr>';
}
html,
body {
  height: 100%;
  margin: 0px;
}
.flexbox {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}
#grid-selected-container {
  flex-basis: 30%;
  flex-grow: 0;
  flex-shrink: 0;
  align-self: stretch;
}
#grid-available-container {
  flex-grow: 1;
  flex-shrink: 1;
  align-self: stretch;
  height: 100%;
  overflow: auto;
}
<div class="flexbox">
  <div id="grid-selected-container">
    <table width="100%" class="display" id="grid-selected">
      <tr>
        <td>placeholder</td>
      </tr>
    </table>
  </div>
  <button id="button-render" type="button" class="btn btn-default btn-lg">placeholder</button>
  <div id="grid-available-container">
    <div class="scroll-wrapper">
      <div class="fixed-head">
        <table width="100%" class="display">
          <thead>
            <th>header</th>
          </thead>
        </table>
      </div>
      <div class="scroll-body">
        <table width="100%" class="display" id="grid-available">
          <tbody id="table-body">
          </tbody>
        </table>
      </div>
    </div>
  </div>
</div>

但我不想滚动整个 flex 元素。我想滚动表体,即 scroll-body div。 fixed-head,其中包含表头等内容,不应滚动到 View 之外。这是我遇到问题的地方:

var node = document.getElementById("table-body");
for (var i = 0; i < 200; i++) {
  node.innerHTML += '<tr><td>' + i + '</td></tr>';
}
html,
body {
  height: 100%;
  margin: 0px;
}
.flexbox {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}
#grid-selected-container {
  flex-basis: 30%;
  flex-grow: 0;
  flex-shrink: 0;
  align-self: stretch;
}
#grid-available-container {
  flex-grow: 1;
  flex-shrink: 1;
  align-self: stretch;
  height: 100%;
}
.scroll-wrapper {
  height: 100%;
}
.scroll-body {
  height: 100%;
  overflow: auto;
}
<div class="flexbox">
  <div id="grid-selected-container">
    <table width="100%" class="display" id="grid-selected">
      <tr>
        <td>placeholder</td>
      </tr>
    </table>
  </div>
  <button id="button-render" type="button" class="btn btn-default btn-lg">placeholder</button>
  <div id="grid-available-container">
    <div class="scroll-wrapper">
      <div class="fixed-head">
        <table width="100%" class="display">
          <thead>
            <th>header</th>
          </thead>
        </table>
      </div>
      <div class="scroll-body">
        <table width="100%" class="display" id="grid-available">
          <tbody id="table-body">
          </tbody>
        </table>
      </div>
    </div>
  </div>
</div>

要完全允许滚动(overflow: auto),我需要在父元素上设置一个固定的高度——显然 flexbox 是不够的。但是当我将固定高度设置为 100% 时, flex 元素会扩展到整个屏幕的大小,而不是缩小。我希望主体保持不可滚动,因此 flex 元素应该收缩。

如何使 scroll-body div 滚动同时防止滚动到其他地方?


真正的表格是使用 jQuery DataTables 插件呈现的 - 这个问题中的代码只是试图复制结构并重现问题。

最佳答案

注意:截至 2015 年 6 月,这在 Firefox 和 IE (!) 上有效,但在 Chrome 上失败。可能 this Chrome flexbox 错误。

嵌套 flex 布局和绝对定位的可滚动框技巧 humble.rumble 的组合建议:

var node = document.getElementById("table-body");
for (var i = 0; i < 200; i++) {
  node.innerHTML += '<tr><td>' + i + '</td></tr>';
}
html,
body {
  height: 100%;
  margin: 0px;
}
.flexbox {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}
#grid-selected-container {
  flex-basis: 30%;
  flex-grow: 0;
  flex-shrink: 0;
  align-self: stretch;
}
#grid-available-container {
  flex-grow: 1;
  flex-shrink: 1;
  align-self: stretch;
}
.scroll-wrapper {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  height: 100%;
}
.scroll-body {
  position: relative;
  height: 100%;
}
.scroll-body tbody {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  overflow: auto;
}
<div class="flexbox">
  <div id="grid-selected-container">
    <table width="100%" class="display" id="grid-selected">
      <tr>
        <td>placeholder</td>
      </tr>
    </table>
  </div>
  <button id="button-render" type="button" class="btn btn-default btn-lg">placeholder</button>
  <div id="grid-available-container">
    <div class="scroll-wrapper">
      <div class="fixed-head">
        <table width="100%" class="display" id="grid-available">
          <thead>
            <th>header</th>
          </thead>
        </table>
      </div>
      <div class="scroll-body">
        <table width="100%" class="display" id="grid-available">
          <tbody id="table-body">
          </tbody>
        </table>
      </div>
    </div>
  </div>
</div>

共有三层。首先,一个 flex 布局 (.scroll-wrapper) 将表头和表体作为其子项。 flex 布局将负责让固定标题占用尽可能多的空间,并用主体填充其余部分。

然后实际的可滚动区域是两个 block 布局 div(在这种情况下,一个 div 和一个 tbody)。第一层(.scroll-body)是相对定位的 block ,填充了 flex 的其余部分,第二层(.scroll-body)是可滚动内容所在的绝对定位 block - 绝对定位可防止它扩展第一级。

关于html - 如何使 flexbox 元素的后代元素可滚动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30657735/

相关文章:

javascript - 在 ONCLICK 事件上调用函数

php - 如何在PHP中获取第一个值

html - float html 元素的奇怪行为

javascript - 是否可以设置 cssRule 的 cssText 属性

CSS :first-child unexpectedly working fine

html - 使用 flexbox 在不同的断点改变布局

javascript - 如何在动态创建的文本框中设置值

html - flex align-items 中心不居中

html - 如何结合 flexbox order 和 nth-child(odd)

html - 如何使 “grid-(row or column): span 2” 在较小的设备上做出响应?