html - 设置溢出 : scroll on a table with display: flex

标签 html css overflow flexbox

我有一个带有 display: flex 属性的表格,其单元格将垂直居中。当单元格的数量超过表格可以显示的数量时,overflow: scroll 属性不会考虑顶部的单元格。

在下面的示例代码中,滚动在字母 K 处停止,而本应一直向上滚动到字母 A。这是什么原因造成的?

#container {
  height: 180px;
  display: flex;
  flex-flow: row;
  align-items: stretch;
  border: 1px dashed gray;
}

table {
  display: flex;
  flex-flow: row;
  align-items: center;
  margin: 10px;
  overflow: scroll;
  border: 1px dashed blue;
}

td {
  height: 10px;
  width: 100px;
  border: 1px solid red;
}

#container div {
  flex: 1;
  margin: 10px;
  border: 1px dashed red;
}
<div id="container">
  <table>
    <tr><td>A</td></tr>
    <tr><td>B</td></tr>
    <tr><td>C</td></tr>
    <tr><td>D</td></tr>
    <tr><td>E</td></tr>
    <tr><td>F</td></tr>
    <tr><td>G</td></tr>
    <tr><td>H</td></tr>
    <tr><td>I</td></tr>
    <tr><td>J</td></tr>
    <tr><td>K</td></tr>
    <tr><td>L</td></tr>
    <tr><td>M</td></tr>
    <tr><td>N</td></tr>
    <tr><td>O</td></tr>
    <tr><td>P</td></tr>
    <tr><td>Q</td></tr>
    <tr><td>R</td></tr>
    <tr><td>S</td></tr>
    <tr><td>T</td></tr>
    <tr><td>U</td></tr>
    <tr><td>V</td></tr>
    <tr><td>W</td></tr>
    <tr><td>X</td></tr>
    <tr><td>Y</td></tr>
    <tr><td>Z</td></tr>
  </table>
  <table>
    <tr><td>A</td></tr>
    <tr><td>B</td></tr>
    <tr><td>C</td></tr>
  </table>
  <div></div>
</div>

最佳答案

根据HTML spec , 浏览器必须包装 <tr> <tbody> 中的元素如果没有元素:

<tbody> is inserted inside <table> (http://jsfiddle.net/ed9msnfp/)

那个<tbody>的高度将是所有行的高度。但是,<table> 的高度可以更小。这在表格布局中不是问题,因为表格的高度将被视为最小高度。

然而,<table>现在参与 flex 布局,而不是表格布局。自 <tbody>table-row-group父元素既不是 table 的元素也不inline-table (这是一个 flex ),一个 anonymous table父级生成。

The <tbody> is wrapped in an anonymous table (http://jsfiddle.net/1wf1hu0d/)

所以现在我们有一个 <table>这是一个带有单个 flex 行的 flex 容器,它包含一个 flex 元素(匿名 table )。

flex 行的高度将是 flex 容器的高度 ( spec ):

If the flex container is single-line and has a definite cross size, the cross size of the flex line is the flex container’s inner cross size.

然后你使用 align-items: center .这将垂直对齐匿名 table (与 <tbody> 一起)在 flex 线的中间,即使它溢出上方或下方也是如此。

问题是滚动条允许滚动看到下面溢出的内容,但是不能看到上面溢出的内容。

因此,而不是 align-items: center , 我建议 aligning with auto margins :

Prior to alignment via justify-content and align-self, any positive free space is distributed to auto margins in that dimension.

请注意区别:自动边距仅分配可用空间,而不分配负数。

因此,我们只需为 flex 元素设置样式

margin: auto 0; /* Push to the center (vertically) */

但是有一个问题:正如上面所解释的,flex item是一个匿名生成的元素,所以我们不能用CSS选择器来选择它。

为了解决这个问题,我们可以添加 display: block<tbody> .然后,它不会被包裹在任何匿名 table 中元素,因此它将是一个 flex 元素,并且对齐将起作用。

请注意,这不会破坏表格,因为一堆 <tr> s,它们是 table-row s, 会生成一个匿名的table parent ,但现在在<tbody>里面:

An anonymous table is generated inside <tbody> (http://jsfiddle.net/bvjvd30u/)

所以你可以使用这段代码:

tbody {
  display: block; /* Disable tabular layout, and make <tbody> a flex item */
  margin: auto 0; /* Push to the center (vertically) */
}

#container {
  height: 180px;
  display: flex;
  flex-flow: row;
  align-items: stretch;
  border: 1px dashed gray;
}
table {
  display: flex;
  flex-flow: row;
  margin: 10px;
  overflow: scroll;
  border: 1px dashed blue;
}
tbody {
  display: block; /* Disable tabular layout, and make <tbody> a flex item */
  margin: auto 0; /* Push to the center (vertically) */
}
td {
  height: 10px;
  width: 100px;
  border: 1px solid red;
}
#container div {
  flex: 1;
  margin: 10px;
  border: 1px dashed red;
}
<div id="container">
  <table>
    <tbody>
      <tr><td>A</td></tr>
      <tr><td>B</td></tr>
      <tr><td>C</td></tr>
      <tr><td>D</td></tr>
      <tr><td>E</td></tr>
      <tr><td>F</td></tr>
      <tr><td>G</td></tr>
      <tr><td>H</td></tr>
      <tr><td>I</td></tr>
      <tr><td>J</td></tr>
      <tr><td>K</td></tr>
      <tr><td>L</td></tr>
      <tr><td>M</td></tr>
      <tr><td>N</td></tr>
      <tr><td>O</td></tr>
      <tr><td>P</td></tr>
      <tr><td>Q</td></tr>
      <tr><td>R</td></tr>
      <tr><td>S</td></tr>
      <tr><td>T</td></tr>
      <tr><td>U</td></tr>
      <tr><td>V</td></tr>
      <tr><td>W</td></tr>
      <tr><td>X</td></tr>
      <tr><td>Y</td></tr>
      <tr><td>Z</td></tr>
    </tbody>
  </table>
  <table>
    <tbody>
      <tr><td>A</td></tr>
      <tr><td>B</td></tr>
      <tr><td>C</td></tr>
    </tbody>
  </table>
  <div></div>
</div>

关于html - 设置溢出 : scroll on a table with display: flex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30851336/

相关文章:

c# - 使用 JavaScript 将 visible 属性设置为 false 时删除空白区域

javascript - 限制可以选中的复选框的数量

css - CSV 数据以列格式显示?

css - 如何使用 css 将 div block 放入右侧屏幕区域?

android - 操作栏中的 3 点菜单(选项菜单溢出)是图像还是 android 提供的默认图标?

javascript - 单击输入的标签会触发两次单击

html - 用图像替换 anchor 文本

html - 是否可以将 CSS @media 规则内联?

html - CSS 'overflow' 属性问题

html - 获取溢出-y :scroll to work with fixed positioning html & css