html - 固定标题 HTML 表格上的额外水平滚动条?
问题描述
我有一些包含很多列的 HTML 表格。我目前正在尝试升级这些表以具有固定的标题,所以我在网上浏览了一些示例,这些示例说要固定表布局,thead 和 tbody 块,限制 tbody 的高度,并在 tbody 上设置溢出-y。一切正常,我的数据滚动,而标题保持不变。
但是,每当我有足够的列宽度溢出视口时,我就会得到两个我没有要求的水平滚动条。我没有在任何地方设置溢出或溢出-x,但我得到了两个水平滚动条——一个只用于 tbody,一个用于整个表格。使用 tbody 滚动显示所有数据,但将标题保留在适当的位置,因此它们不会与数据对齐,并且滚动 table one 不允许您查看原始视口之外的数据,因为有一个垂直滚动条视口的右边缘最初是。
我实际上使用的是旧版本的 Vuetify(不,我无法升级),但我已经缩小了很多范围,并在这里用一个简单的 HTML/CSS-only 示例重现了这个问题。任何人都可以向我解释水平滚动条的来源吗?我确实想要一个水平滚动条,可能是表格的那个,但我希望它同时滚动数据和标题。大概摆脱 tbody 滚动条会做到这一点,但我没有在任何地方定义它,所以我不知道如何删除它。事实上,检查员根本没有在任何地方显示溢出-x!我尝试将 overflow-x 添加到各种元素以尝试强制滚动条,以便这些自动滚动条不需要显示,但到目前为止还没有运气。
在此先感谢您的任何建议!
示例 CSS:
table {
table-layout: fixed;
width: 100%;
}
thead tr, tbody {
display: block;
}
tbody {
height: 300px;
overflow-y: auto;
}
th, td {
width: 100px;
min-width: 100px;
}
示例 HTML:
<html>
<div style="max-width: 500px; overflow-y: auto;">
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td>
<td>Data2</td>
<td>Data3</td>
<td>Data4</td>
<td>Data5</td>
<td>Data6</td>
<td>Data7</td>
<td>Data8</td>
<tr>
<tr>
<td>Data1</td>
<td>Data2</td>
<td>Data3</td>
<td>Data4</td>
<td>Data5</td>
<td>Data6</td>
<td>Data7</td>
<td>Data8</td>
<tr>
<!-- more rows to make it scroll vertically -->
</tbody>
</table>
</div>
</html>
解决方案
您正在谈论的滚动条正在添加到tbody
元素中。通过tbody
变成一个块,overscroll:auto
默认情况下会被添加,即使你只包含overflow-y
在你的 CSS 中:
thead tr, tbody {
display: block;
}
tbody {
height: 300px;
overflow-y: auto;
}
部分解决方案(在没有水平溢出时有效)
添加overflow-y:hidden
到tbody
将删除第二个水平滚动条,这在没有水平溢出时有效。但是,如果有,垂直滚动条会“卡在”位于最大宽度的列上并与 tbody 一起滚动,如您在此处看到的:
table {
table-layout: fixed;
width: 100%;
}
thead tr, tbody {
display: block;
}
tbody {
height: 300px;
overflow-y: auto;
overflow-x: hidden;
}
th, td {
width: 100px;
min-width: 100px;
}
<html>
<div style="max-width: 500px; overflow-y: auto;">
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
</tbody>
</table>
</div>
</html>
最大的问题是使tbody
滚动独立于thead
垂直方向(我们想要这样做,因为我们想要保留标题)也会阻止它在水平滚动上工作(我们不会这样做,因为标题不会随 tbody 移动)。
水平和垂直溢出的纯 CSS 解决方案(部分浏览器支持)
当表格的其余部分在其后面向上滚动时,使用position:sticky
标题行将使其保持在表格的顶部:
th {
position: sticky;
top: 0;
background: #FFF; /* otherwise we can see the scrolling data behind it */
}
table {
/* prevent the th scrolling up by the default border size before "sticking" */
border-collapse: collapse;
}
然而,这只有部分浏览器支持。请注意,它仅适用于th
(而不是thead
or tr
)在 Chrome、FF 和其他中。
工作示例(或不,取决于您的浏览器!):
table {
table-layout: fixed;
width: 100%;
/* the prevents the th scrolling up by the default border size before "sticking" */
border-collapse: collapse;
}
th, td {
width: 100px;
min-width: 100px;
}
th {
position: sticky;
top: 0;
background: #FFF;
}
<html>
<p>This is some content to show the effect of the sticky header and top:0 on the rest of the page </p>
<div style="max-width: 500px; height:200px; overflow: auto;">
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
</tbody>
</table>
</div>
<p>This is some content to show the effect of the sticky header and top:0 on the rest of the page </p>
</html>
Javascript/jQuery 解决方案
这被标记为 CSS 和 HTML,但我在这里只提到这一点,因为 JS 是在最广泛的浏览器支持下做到这一点的唯一可靠方法。
- 来自“Springborg”的 Codepen 有 2 个选项:https ://codepen.io/springborg/pen/MvPmPP
- 这个 SO 问题有多种方法可以克隆表格以分别创建标题行:Fixed table header with Horizontal AND Vertical scrolling body
Salman A 对该问题的回答创建了表格的克隆,并显示了<thead>
第一个和<tbody>
第二个。这在您的示例中很容易实现 - 见下文:
$(function() {
$(".fixed_headers").each(function() {
$(this).wrap("<div class='scrollable-table'></div>");
$(this).clone().insertBefore(this);
});
});
.scrollable-table {
overflow: auto;
max-height: 200px;
}
.scrollable-table table:nth-child(1) {
position: sticky;
left: 0;
top: 0;
background-color: #fff;
margin-bottom: 0;
}
.scrollable-table table:nth-child(1) tbody {
visibility: collapse;
}
.scrollable-table table:nth-child(2) thead {
visibility: collapse;
}
th, td {
width: 100px;
min-width: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<div style="max-width: 500px;">
<table class="fixed_headers">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
</tbody>
</table>
</div>
</html>
推荐阅读
- sql - 在 Snowflake 的公用表表达式中使用“match_recognize”
- email - 使用 Google Apps 脚本阻止的电子邮件
- c# - 带有 .NET Core 类库的 DLL Hell
- python - 不知道如何在 Python 中安装滑板包?
- javascript - 如何在vue中清除模态表单内的值
- r - tidymodels 列中发现的新级别
- pyspark - 如何从 Pyspark 中的另一列中获取包含值列表的列
- wayland - 非 XDG Wayland 应用程序的示例?
- character - 如何选择出现在多个不连续行中的同一组字符,然后将这些标记的整个行复制到新的记事本中?
- swift - How can I be sure that I am accessing the correct value to use in Swift