我有一个带有 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>
的高度将是所有行的高度。但是,<table>
的高度可以更小。这在表格布局中不是问题,因为表格的高度将被视为最小高度。
然而,<table>
现在参与 flex 布局,而不是表格布局。自 <tbody>
是 table-row-group
父元素既不是 table
的元素也不inline-table
(这是一个 flex
),一个 anonymous table
父级生成。
所以现在我们有一个 <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
andalign-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>
里面:
所以你可以使用这段代码:
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/