设置溢出:在 table 上滚动显示:flex
Setting overflow: scroll on a table with display: flex
我有一个 table 和 display: flex
属性,其单元格将垂直居中。当单元格多于 table 可以显示时,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 布局中不是问题,因为 table 的高度将被视为最小高度。
但是,<table>
现在参与了 flex 布局,而不是 table 布局。由于 <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>
),即使它溢出上方或下方。
问题是滚动条允许滚动看到下面溢出的内容,但不能看到上面溢出的内容。
因此,我建议 aligning with auto margins:
而不是 align-items: center
Prior to alignment via justify-content
and align-self
,
any positive free space is distributed to auto margins in that
dimension.
注意区别:自动边距仅分配 正 免费 space,不分配负数。
因此,我们只需要使用
来设置弹性项目的样式
margin: auto 0; /* Push to the center (vertically) */
但是有一个问题:正如上面所解释的,flex item是一个匿名生成的元素,所以我们不能select它与CSS selectors.
要解决这个问题,我们可以将 display: block
添加到 <tbody>
。然后,它不会被包裹在任何匿名 table
元素中,因此它将是一个 flex 项目并且对齐会起作用。
请注意,这不会破坏 table,因为 <tr>
的一堆 table-row
将生成一个匿名的 table
父级,但是现在在 <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>
请访问 - https://jsfiddle.net/3y80zqzc/1/
您将观察到 tbody
新添加的 class。 边距参数 是最重要的,它确保内容的垂直中间位置。
margin: auto, 0; /*this is for vertically middle position*/
margin: 0, auto; /*this is for horizontally center position*/
您还可以查看 HTML 代码
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<style>
#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;
}
tbody {
display: block;
margin: auto 0;
}
</style>
</head>
<body>
<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>
</body>
</html>
我有一个 table 和 display: flex
属性,其单元格将垂直居中。当单元格多于 table 可以显示时,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 布局中不是问题,因为 table 的高度将被视为最小高度。
但是,<table>
现在参与了 flex 布局,而不是 table 布局。由于 <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>
),即使它溢出上方或下方。
问题是滚动条允许滚动看到下面溢出的内容,但不能看到上面溢出的内容。
因此,我建议 aligning with auto margins:
而不是align-items: center
Prior to alignment via
justify-content
andalign-self
, any positive free space is distributed to auto margins in that dimension.
注意区别:自动边距仅分配 正 免费 space,不分配负数。
因此,我们只需要使用
来设置弹性项目的样式margin: auto 0; /* Push to the center (vertically) */
但是有一个问题:正如上面所解释的,flex item是一个匿名生成的元素,所以我们不能select它与CSS selectors.
要解决这个问题,我们可以将 display: block
添加到 <tbody>
。然后,它不会被包裹在任何匿名 table
元素中,因此它将是一个 flex 项目并且对齐会起作用。
请注意,这不会破坏 table,因为 <tr>
的一堆 table-row
将生成一个匿名的 table
父级,但是现在在 <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>
请访问 - https://jsfiddle.net/3y80zqzc/1/
您将观察到 tbody
新添加的 class。 边距参数 是最重要的,它确保内容的垂直中间位置。
margin: auto, 0; /*this is for vertically middle position*/
margin: 0, auto; /*this is for horizontally center position*/
您还可以查看 HTML 代码
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<style>
#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;
}
tbody {
display: block;
margin: auto 0;
}
</style>
</head>
<body>
<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>
</body>
</html>