为了使<tbody> 元素可滚动,我们需要更改它在页面上的显示方式,即使用display: block; 将其显示为块级元素。
由于我们更改了tbody 的display 属性,我们也应该更改thead 元素的该属性,以防止破坏表格布局。
所以我们有:
thead, tbody { display: block; }
tbody {
height: 100px; /* Just for the demo */
overflow-y: auto; /* Trigger vertical scroll */
overflow-x: hidden; /* Hide the horizontal scroll */
}
Web 浏览器默认将thead 和tbody 元素显示为行组(table-header-group 和table-row-group)。
一旦我们改变它,内部的tr 元素就不会填满它们容器的整个空间。
为了解决这个问题,我们必须计算 tbody 列的宽度,并通过 JavaScript 将相应的值应用于 thead 列。
自动宽度列
这是上述逻辑的jQuery版本:
// Change the selector if needed
var $table = $('table'),
$bodyCells = $table.find('tbody tr:first').children(),
colWidth;
// Get the tbody columns width array
colWidth = $bodyCells.map(function() {
return $(this).width();
}).get();
// Set the width of thead columns
$table.find('thead tr').children().each(function(i, v) {
$(v).width(colWidth[i]);
});
这是输出(在 Windows 7 Chrome 32 上):
WORKING DEMO.
全宽表格,相对宽度列
根据原始海报的需要,我们可以将 table 扩展到其容器的 width 的 100%,然后使用相对(百分比)width 用于表。
table {
width: 100%; /* Optional */
}
tbody td, thead th {
width: 20%; /* Optional */
}
由于表格具有(某种)流动布局,我们应该在容器调整大小时调整thead 列的宽度。
因此我们应该在调整窗口大小后设置列的宽度:
// Adjust the width of thead cells when *window* resizes
$(window).resize(function() {
/* Same as before */
}).resize(); // Trigger the resize handler once the script runs
输出将是:
WORKING DEMO.
浏览器支持和替代品
我在 Windows 7 上通过新版本的主要 Web 浏览器(包括 IE10+)测试了上述两种方法,并且成功了。
但是,doesn'tworkproperlyon IE9 及以下。
这是因为在table layout 中,所有元素都应遵循相同的结构属性。
通过将display: block; 用于<thead> 和<tbody> 元素,我们破坏了表结构。
通过 JavaScript 重新设计布局
一种方法是重新设计(整个)表格布局。使用 JavaScript 动态创建新布局并动态处理和/或调整单元格的宽度/高度。
例如,看看下面的例子:
嵌套表
这种方法使用两个嵌套表,其中包含一个 div。第一个table 只有一个单元格有div,第二个表格放在div 元素内。
在CSS Play查看Vertical scrolling tables。
这适用于大多数网络浏览器。我们也可以通过 JavaScript 动态地完成上述逻辑。
滚动时带有固定标题的表格
由于向<tbody> 添加垂直滚动条的目的是在每一行的顶部显示表格标题,我们可以定位 thead 元素而是将fixed 留在屏幕顶部。
这是 Julien 执行的这种方法的 Working Demo。
它有一个很有前途的网络浏览器支持。
而here 是由Willem Van Bockstal 实现的pure CSS。
纯 CSS 解决方案
这是旧答案。当然,我添加了一个新方法并改进了 CSS 声明。
固定宽度的表格
在这种情况下,table 应该有一个固定的width(包括列宽和垂直滚动条的宽度之和)。
每个列应该有一个特定的宽度,而thead元素的最后一列需要更大的宽度 等于别人的width + 垂直滚动条的width。
因此,CSS 将是:
table {
width: 716px; /* 140px * 5 column + 16px scrollbar width */
border-spacing: 0;
}
tbody, thead tr { display: block; }
tbody {
height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
tbody td, thead th {
width: 140px;
}
thead th:last-child {
width: 156px; /* 140px + 16px scrollbar width */
}
这是输出:
WORKING DEMO.
100% 宽度的表格
在这种方法中,table 的宽度为100%,对于每个th 和td,width 属性的值应小于100% / number of cols。
另外,我们需要减小thead的width作为垂直滚动条width的值。
为此,我们需要使用 CSS3 calc() 函数,如下:
table {
width: 100%;
border-spacing: 0;
}
thead, tbody, tr, th, td { display: block; }
thead tr {
/* fallback */
width: 97%;
/* minus scroll bar width */
width: -webkit-calc(100% - 16px);
width: -moz-calc(100% - 16px);
width: calc(100% - 16px);
}
tr:after { /* clearing float */
content: ' ';
display: block;
visibility: hidden;
clear: both;
}
tbody {
height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
tbody td, thead th {
width: 19%; /* 19% is less than (100% / 5 cols) = 20% */
float: left;
}
这里是Online Demo。
注意:如果每一列的内容都换行,这种方法将失败,即每个单元格的内容应该足够短 .
下面是我在回答这个问题时创建的纯 CSS 解决方案的两个简单示例。
这里是jsFiddle Demo v2。
旧版本:jsFiddle Demo v1