关于css:宽度为100%的HTML表格,在tbody中有垂直滚动

HTML table with 100% width, with vertical scroll inside tbody

如何设置

100%宽度,只放在

垂直卷轴内一定高度?

vertical scroll inside tbody

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
table {
    width: 100%;
    display:block;
}
thead {
    display: inline-block;
    width: 100%;
    height: 20px;
}
tbody {
    height: 200px;
    display: inline-block;
    width: 100%;
    overflow: auto;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<table>
  <thead>
    <tr>
        <th>Head 1</th>
        <th>Head 2</th>
        <th>Head 3</th>
        <th>Head 4</th>
        <th>Head 5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
    </tr>
  </tbody>
</table>

我想避免添加一些额外的DIV,我想要的只是这样简单的表,当我试图改变显示时,table-layoutposition和CSS表中的很多东西在100%宽度的情况下工作不好,只有在px中有固定的宽度。


为了使

元素可滚动,我们需要改变它在页面上的显示方式,即使用display: block;将其显示为块级元素。好的。

由于我们改变了tbodydisplay属性,我们应该改变thead元素的display属性,防止破坏表的布局。好的。

所以我们有:好的。

1
2
3
4
5
6
7
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浏览器默认将theadtbody元素显示为行组(table-header-grouptable-row-group)。好的。

一旦我们改变了这一点,内部的tr元素就不会填满容器的整个空间。好的。

为了解决这个问题,我们必须计算tbody列的宽度,并通过javascript将相应的值应用到thead列。好的。自动调整列宽

下面是上述逻辑的jquery版本:好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 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]);
});

下面是输出(在Windows7Chrome32上):好的。

vertical scroll inside tbody好的。

工作演示。好的。全宽表格,相对宽度列

根据原始海报的需要,我们可以将table扩展到容器width的100%,然后对表中的每一列使用相对(百分比)width。好的。

1
2
3
4
5
6
7
table {
    width: 100%; /* Optional */
}

tbody td, thead th {
    width: 20%;  /* Optional */
}

由于表具有(某种)流体布局,因此当容器调整大小时,我们应该调整thead列的宽度。好的。

因此,我们应该在调整窗口大小后设置列的宽度:好的。

1
2
3
4
// Adjust the width of thead cells when *window* resizes
$(window).resize(function() {
    /* Same as before */
}).resize(); // Trigger the resize handler once the script runs

输出将是:好的。

Fluid Table with vertical scroll inside tbody好的。

工作演示。好的。浏览器支持和替代方案

我已经通过主要Web浏览器(包括IE10+)的新版本在Windows7上测试了上述两种方法,并且它工作正常。好的。

但是,它在IE9及以下版本上无法正常工作。好的。

这是因为在表布局中,所有元素都应该遵循相同的结构属性。好的。

通过对

元素使用display: block;,我们打破了表结构。好的。通过javascript重新设计布局

一种方法是重新设计(整个)表布局。使用javascript动态创建新布局,并动态处理和/或调整单元格的宽度/高度。好的。

例如,请看以下示例:好的。

  • jquery.floatThead()插件(浮动/锁定/粘性表头插件)
  • jquery可滚动表插件。(Github上的源代码)
  • jquery.fixedHeaderTable()插件(GitHub上的源代码)
  • 数据表垂直滚动示例。

嵌套表

这种方法使用两个嵌套表和一个包含DIV。第一个table只有一个单元格具有div,第二个表放在div元素中。好的。

在CSS播放时检查垂直滚动表。好的。

这适用于大多数Web浏览器。我们还可以通过JavaScript动态地执行上述逻辑。好的。卷轴上带固定标题的表格

由于向

添加垂直滚动条的目的是在每一行的顶部显示表标题,因此我们可以将thead元素定位为将fixed保留在屏幕顶部。好的。

下面是Julien执行的这个方法的一个工作演示。它有很好的网络浏览器支持。好的。

这里是WillemvanBockstal的纯CSS实现。好的。纯CSS解决方案

这是老答案。当然,我已经添加了一个新方法并改进了CSS声明。好的。固定宽度的桌子

在这种情况下,table应该有一个固定的width(包括列宽度和垂直滚动条宽度之和)。好的。

每列应有一个特定的宽度,thead元素的最后一列需要一个更大的宽度,该宽度等于其他列的宽度+垂直滚动条的宽度。好的。

因此,CSS将是:好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 */
}

以下是输出:好的。

Table with Fixed Width好的。

工作演示。好的。100%宽度的桌子

在这种方法中,table的宽度为100%,对于每个thtdwidth属性的值应小于100% / number of cols。好的。

另外,我们需要将thead的宽度减小为垂直滚动条宽度的值。好的。

为此,我们需要使用css3 calc()函数,如下所示:好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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;
}

这是在线演示。好的。

注意:如果每一列的内容换行,即每个单元格的内容应该足够短,则此方法将失败。好的。

下面是我回答这个问题时创建的两个简单的纯CSS解决方案示例。好的。

这里是jsFiddle演示版v2。好的。

旧版本:jsFiddle演示v1好的。好啊。


在下面的解决方案中,表占父容器的100%,不需要绝对大小。它是纯CSS,使用了flex布局。

这是它的样子:enter image description here

可能的缺点:

  • 垂直滚动条始终可见,无论是否需要;
  • 表布局是固定的-列不根据内容宽度调整大小(您仍然可以显式设置所需的列宽);
  • 有一个绝对大小——滚动条的宽度,对于我能够检查的浏览器来说,它大约是0.9em。

HTML(缩写):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    <table>
        <thead>
            <tr>
                <th>head1</th>
                <th>head2</th>
                <th>head3</th>
                <th>head4</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            ...
        </tbody>
    </table>

为清晰起见,省略了一些装饰:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.table-container {
    height: 10em;
}
table {
    display: flex;
    flex-flow: column;
    height: 100%;
    width: 100%;
}
table thead {
    /* head takes the height it requires,
    and it's not scaled when table is resized */

    flex: 0 0 auto;
    width: calc(100% - 0.9em);
}
table tbody {
    /* body takes all the remaining available space */
    flex: 1 1 auto;
    display: block;
    overflow-y: scroll;
}
table tbody tr {
    width: 100%;
}
table thead, table tbody tr {
    display: table;
    table-layout: fixed;
}

JSfiddle上的完整代码

相同的代码更少,因此您可以将其混合在:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.table-scrollable() {
  @scrollbar-width: 0.9em;
  display: flex;
  flex-flow: column;

  thead,
  tbody tr {
    display: table;
    table-layout: fixed;
  }

  thead {
    flex: 0 0 auto;
    width: ~"calc(100% - @{scrollbar-width})";
  }

  tbody {
    display: block;
    flex: 1 1 auto;
    overflow-y: scroll;

    tr {
      width: 100%;
    }
  }
}


我用display:block来表示theadtbody。因此,thead列的宽度不同于tbody列的宽度。

1
2
3
4
5
6
7
8
9
10
11
12
table {
    margin:0 auto;
    border-collapse:collapse;
}
thead {
    background:#CCCCCC;
    display:block
}
tbody {
    height:10em;overflow-y:scroll;
    display:block
}

为了解决这个问题,我使用了小的jQuery代码,但它只能在JavaScript中完成。

1
2
3
4
5
6
7
8
9
10
var colNumber=3 //number of table columns    

for (var i=0; i<colNumber; i++) {
  var thWidth=$("#myTable").find("th:eq("+i+")").width();
  var tdWidth=$("#myTable").find("td:eq("+i+")").width();      
  if (thWidth<tdWidth)                    
      $("#myTable").find("th:eq("+i+")").width(tdWidth);
  else
      $("#myTable").find("td:eq("+i+")").width(thWidth);          
}

这是我的工作演示:http://jsfiddle.net/gavroche/n7lef/

在IE 8中不工作

1
2
3
4
5
6
7
8
9
10
11
12
var colNumber=3 //number of table columns


for (var i=0; i<colNumber; i++)
  {
      var thWidth=$("#myTable").find("th:eq("+i+")").width();
      var tdWidth=$("#myTable").find("td:eq("+i+")").width();      
      if (thWidth<tdWidth)                    
          $("#myTable").find("th:eq("+i+")").width(tdWidth);
      else
          $("#myTable").find("td:eq("+i+")").width(thWidth);          
  }
1
2
3
 table {margin:0 auto; border-collapse:separate;}
 thead {background:#CCCCCC;display:block}
 tbody {height:10em;overflow-y:scroll;display:block}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
<table id="myTable" border="1">
    <thead>
        <tr>
            <th>A really Very Long Header Text</th>
            <th>Normal Header</th>
            <th>Short</th>            
        </tr>    
    </thead>
    <tbody>
        <tr>
            <td>
                Text shorter than header
            </td>
            <td>
                Text is longer than header
            </td>
            <td>
                Exact
            </td>
        </tr>
        <tr>
            <td>
                Text shorter than header
            </td>
            <td>
                Text is longer than header
            </td>
            <td>
                Exact
            </td>
        </tr>
        <tr>
            <td>
                Text shorter than header
            </td>
            <td>
                Text is longer than header
            </td>
            <td>
                Exact
            </td>
        </tr>
        <tr>
            <td>
                Text shorter than header
            </td>
            <td>
                Text is longer than header
            </td>
            <td>
                Exact
            </td>
        </tr>
        <tr>
            <td>
                Text shorter than header
            </td>
            <td>
                Text is longer than header
            </td>
            <td>
                Exact
            </td>
        </tr>
        <tr>
            <td>
                Text shorter than header
            </td>
            <td>
                Text is longer than header
            </td>
            <td>
                Exact
            </td>
        </tr>
        <tr>
            <td>
                Text shorter than header
            </td>
            <td>
                Text is longer than header
            </td>
            <td>
                Exact
            </td>
        </tr>
        <tr>
            <td>
                Text shorter than header
            </td>
            <td>
                Text is longer than header
            </td>
            <td>
                Exact
            </td>
        </tr>
        <tr>
            <td>
                Text shorter than header
            </td>
            <td>
                Text is longer than header
            </td>
            <td>
                Exact
            </td>
        </tr>
        <tr>
            <td>
                Text shorter than header
            </td>
            <td>
                Text is longer than header
            </td>
            <td>
                Exact
            </td>
        </tr>
        <tr>
            <td>
                Text shorter than header
            </td>
            <td>
                Text is longer than header
            </td>
            <td>
                Exact
            </td>
        </tr>
    </tbody>
</table>


在现代浏览器中,您可以简单地使用CSS:

1
2
3
4
5
th {
  position: sticky;
  top: 0;
  z-index: 2;
}


一个接一个地创建两个表,将第二个表放在固定高度的分区中,并将overflow属性设置为auto。同时,将第二个表中的所有TD保持为空。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    <table>
        <thead>
            <tr>
                <th>Head 1</th>
                <th>Head 2</th>
                <th>Head 3</th>
                <th>Head 4</th>
                <th>Head 5</th>
            </tr>
        </thead>
    </table>



    <table>
        <thead>
            <tr>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
            </tr>
        </thead>
        <tbody>
        <tr>
            <td>Content 1</td>
            <td>Content 2</td>
            <td>Content 3</td>
            <td>Content 4</td>
            <td>Content 5</td>
        </tr>
        </tbody>
    </table>


我按照下面的说明使用纯CSS最终获得了正确的结果:

http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/

第一步是设置

显示:block以便应用溢出和高度。从这里开始,需要将

中的行设置为position:relative和display:block,以便它们位于现在可滚动的

的顶部。

tbody, thead { display: block; overflow-y: auto; }

由于

相对定位,每个表单元格都需要一个明确的宽度。

1
2
3
td:nth-child(1), th:nth-child(1) { width: 100px; }
td:nth-child(2), th:nth-child(2) { width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }

但不幸的是,这还不够。当滚动条存在时,浏览器为它分配空间,因此,

的可用空间比

少。注意这会造成轻微的偏差…

我唯一能想到的解决方法是在除最后一列之外的所有列上设置最小宽度。

1
2
3
td:nth-child(1), th:nth-child(1) { min-width: 100px; }
td:nth-child(2), th:nth-child(2) { min-width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }

整个代码笔示例如下:

CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
.fixed_headers {
  width: 750px;
  table-layout: fixed;
  border-collapse: collapse;
}
.fixed_headers th {
  text-decoration: underline;
}
.fixed_headers th,
.fixed_headers td {
  padding: 5px;
  text-align: left;
}
.fixed_headers td:nth-child(1),
.fixed_headers th:nth-child(1) {
  min-width: 200px;
}
.fixed_headers td:nth-child(2),
.fixed_headers th:nth-child(2) {
  min-width: 200px;
}
.fixed_headers td:nth-child(3),
.fixed_headers th:nth-child(3) {
  width: 350px;
}
.fixed_headers thead {
  background-color: #333333;
  color: #fdfdfd;
}
.fixed_headers thead tr {
  display: block;
  position: relative;
}
.fixed_headers tbody {
  display: block;
  overflow: auto;
  width: 100%;
  height: 300px;
}
.fixed_headers tbody tr:nth-child(even) {
  background-color: #dddddd;
}
.old_ie_wrapper {
  height: 300px;
  width: 750px;
  overflow-x: hidden;
  overflow-y: auto;
}
.old_ie_wrapper tbody {
  height: auto;
}

Html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<!-- IE < 10 does not like giving a tbody a height.  The workaround here applies the scrolling to a wrapped . -->
<!--[if lte IE 9]>

<!--<![endif]-->

<table class="fixed_headers">
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Grape</td>
      <td>Purple / Green</td>
      <td>These are purple and green.</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Yellow</td>
      <td>These are yellow.</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Plum</td>
      <td>Purple</td>
      <td>These are Purple</td>
    </tr>
    <tr>
      <td>Watermelon</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Tomato</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Cherry</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Cantelope</td>
      <td>Orange</td>
      <td>These are orange inside.</td>
    </tr>
    <tr>
      <td>Honeydew</td>
      <td>Green</td>
      <td>These are green inside.</td>
    </tr>
    <tr>
      <td>Papaya</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Raspberry</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Blueberry</td>
      <td>Blue</td>
      <td>These are blue.</td>
    </tr>
    <tr>
      <td>Mango</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Passion Fruit</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
  </tbody>
</table>

<!--[if lte IE 9]>

<!--<![endif]-->

编辑:表宽100%的替代解决方案(上面实际上是固定宽度,没有回答问题):

HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Grape</td>
      <td>Purple / Green</td>
      <td>These are purple and green.</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Yellow</td>
      <td>These are yellow.</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
  </tbody>
</table>

CSS:

10

演示:http://codepen.io/anon/pen/bnjelo


尝试下面的方法,非常简单容易实现

下面是jsFiddle链接

http://jsfiddle.net/v2t2k8ke/2/

HTML:

1
2
<table border='1' id='tbl_cnt'>
<thead><tr></tr></thead><tbody></tbody>

CSS:

1
2
3
4
5
6
7
8
9
10
11
12
 #tbl_cnt{
 border-collapse: collapse; width: 100%;word-break:break-all;
 }
 #tbl_cnt thead, #tbl_cnt tbody{
 display: block;
 }
 #tbl_cnt thead tr{
 background-color: #8C8787; text-align: center;width:100%;display:block;
 }
 #tbl_cnt tbody {
 height: 100px;overflow-y: auto;overflow-x: hidden;
 }

jQuery:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 var data = [
    {
   "status":"moving","vehno":"tr544","loc":"bng","dri":"ttt"
    }, {
   "status":"stop","vehno":"tr54","loc":"che","dri":"ttt"
    },{   "status":"idle","vehno":"yy5499999999999994","loc":"bng","dri":"ttt"
    },{
   "status":"moving","vehno":"tr544","loc":"bng","dri":"ttt"
    }, {
   "status":"stop","vehno":"tr54","loc":"che","dri":"ttt"
    },{
   "status":"idle","vehno":"yy544","loc":"bng","dri":"ttt"
    }
    ];
   var sth = '';
   $.each(data[0], function (key, value) {
     sth += '<td>' + key + '</td>';
   });
   var stb = '';        
   $.each(data, function (key, value) {
       stb += '<tr>';
       $.each(value, function (key, value) {
       stb += '<td>' + value + '</td>';
       });
       stb += '</tr>';
    });
      $('#tbl_cnt thead tr').append(sth);
      $('#tbl_cnt tbody').append(stb);
      setTimeout(function () {
      var col_cnt=0
      $.each(data[0], function (key, value) {col_cnt++;});    
      $('#tbl_cnt thead tr').css('width', ($("#tbl_cnt tbody") [0].scrollWidth)+ 'px');
      $('#tbl_cnt thead tr td,#tbl_cnt tbody tr td').css('width',  ($('#tbl_cnt thead tr ').width()/Number(col_cnt)) + 'px');}, 100)


使用"块"tbody强制列正确显示的CSS解决方案

这个解决方案仍然需要jquery计算和设置th宽度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
table.scroll tbody,
table.scroll thead { display: block; }

table.scroll tbody {
    overflow-y: auto;
    overflow-x: hidden;
    max-height: 300px;
}

table.scroll tr {
    display: flex;
}

table.scroll tr > td {
    flex-grow: 1;
    flex-basis: 0;
}

以及jquery/javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var $table = $('#the_table_element'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

$table.addClass('scroll');

// Adjust the width of thead cells when window resizes
$(window).resize(function () {

    // 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]);
    });

}).resize(); // Trigger resize handler


仅CSS

适用于Chrome、Firefox、Edge(和其他常青浏览器)

只需position: sticky; top: 0;您的th元素:

1
2
3
4
5
6
7
8
/* Fix table head */
.tableFixHead    { overflow-y: auto; height: 100px; }
.tableFixHead th { position: sticky; top: 0; }

/* Just common table stuff. */
table  { border-collapse: collapse; width: 100%; }
th, td { padding: 8px 16px; }
th     { background:#eee; }
1
2
3
4
5
6
7
8
9
10
11
12
  <table>
    <thead>
      <tr><th>TH 1</th><th>TH 2</th></tr>
    </thead>
    <tbody>
      <tr><td>A1</td><td>A2</td></tr>
      <tr><td>B1</td><td>B2</td></tr>
      <tr><td>C1</td><td>C2</td></tr>
      <tr><td>D1</td><td>D2</td></tr>
      <tr><td>E1</td><td>E2</td></tr>
    </tbody>
  </table>

为了适应IE11,上面的变体只使用了一点JS,请参阅以下答案:https://stackoverflow.com/a/47923622/383904


这是我在带有可滚动tbody的表上创建粘性thead的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
table ,tr td{
    border:1px solid red
}
tbody {
    display:block;
    height:50px;
    overflow:auto;
}
thead, tbody tr {
    display:table;
    width:100%;
    table-layout:fixed;/* even columns width , fix width of table too*/
}
thead {
    width: calc( 100% - 1em )/* scrollbar is average 1em/16px width, remove it from thead width */
}
table {
    width:400px;
}

将固定宽度添加到td,th使tbody&thead显示块工作正常后,我们还可以使用SlimScroll插件使滚动条更漂亮。

enter image description here

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<!DOCTYPE html>
<html>

<head>
     Scrollable table
    <style>
        body {
            font-family: sans-serif;
            font-size: 0.9em;
        }
        table {
            border-collapse: collapse;
            border-bottom: 1px solid #ddd;
        }
        thead {
            background-color: #333;
            color: #fff;
        }
        thead,tbody {
            display: block;
        }
        th,td {
            padding: 8px 10px;
            border: 1px solid #ddd;
            width: 117px;
            box-sizing: border-box;
        }
        tbody {
            height: 160px;
            overflow-y: scroll
        }
    </style>
</head>

<body>

    <table class="example-table">
        <thead>
            <tr>
                <th> Header 1 </th>
                <th> Header 2 </th>
                <th> Header 3 </th>
                <th> Header 4 </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td> Row 1- Col 1 </td>
                <td> Row 1- Col 2 </td>
                <td> Row 1- Col 3 </td>
                <td> Row 1- Col 4 </td>
            </tr>
            <tr>
                <td> Row 2- Col 1 </td>
                <td> Row 2- Col 2 </td>
                <td> Row 2- Col 3 </td>
                <td> Row 2- Col 4 </td>
            </tr>
            <tr>
                <td> Row 3- Col 1 </td>
                <td> Row 3- Col 2 </td>
                <td> Row 3- Col 3 </td>
                <td> Row 3- Col 4 </td>
            </tr>
            <tr>
                <td> Row 4- Col 1 </td>
                <td> Row 4- Col 2 </td>
                <td> Row 4- Col 3 </td>
                <td> Row 4- Col 4 </td>
            </tr>
            <tr>
                <td> Row 5- Col 1 </td>
                <td> Row 5- Col 2 </td>
                <td> Row 5- Col 3 </td>
                <td> Row 5- Col 4 </td>
            </tr>
            <tr>
                <td> Row 6- Col 1 </td>
                <td> Row 6- Col 2 </td>
                <td> Row 6- Col 3 </td>
                <td> Row 6- Col 4 </td>
            </tr>
            <tr>
                <td> Row 7- Col 1 </td>
                <td> Row 7- Col 2 </td>
                <td> Row 7- Col 3 </td>
                <td> Row 7- Col 4 </td>
            </tr>
            <tr>
                <td> Row 8- Col 1 </td>
                <td> Row 8- Col 2 </td>
                <td> Row 8- Col 3 </td>
                <td> Row 8- Col 4 </td>
            </tr>
            <tr>
                <td> Row 9- Col 1 </td>
                <td> Row 9- Col 2 </td>
                <td> Row 9- Col 3 </td>
                <td> Row 9- Col 4 </td>
            </tr>
            <tr>
                <td> Row 10- Col 1 </td>
                <td> Row 10- Col 2 </td>
                <td> Row 10- Col 3 </td>
                <td> Row 10- Col 4 </td>
            </tr>
            <tr>
                <td> Row 11- Col 1 </td>
                <td> Row 11- Col 2 </td>
                <td> Row 11- Col 3 </td>
                <td> Row 11- Col 4 </td>
            </tr>
            <tr>
                <td> Row 12- Col 1 </td>
                <td> Row 12- Col 2 </td>
                <td> Row 12- Col 3 </td>
                <td> Row 12- Col 4 </td>
            </tr>
            <tr>
                <td> Row 13- Col 1 </td>
                <td> Row 13- Col 2 </td>
                <td> Row 13- Col 3 </td>
                <td> Row 13- Col 4 </td>
            </tr>
            <tr>
                <td> Row 14- Col 1 </td>
                <td> Row 14- Col 2 </td>
                <td> Row 14- Col 3 </td>
                <td> Row 14- Col 4 </td>
            </tr>
            <tr>
                <td> Row 15- Col 1 </td>
                <td> Row 15- Col 2 </td>
                <td> Row 15- Col 3 </td>
                <td> Row 15- Col 4 </td>
            </tr>
            <tr>
                <td> Row 16- Col 1 </td>
                <td> Row 16- Col 2 </td>
                <td> Row 16- Col 3 </td>
                <td> Row 16- Col 4 </td>
            </tr>
        </tbody>
    </table>


    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-slimScroll/1.3.8/jquery.slimscroll.min.js">
   
        $('.example-table tbody').slimscroll({
            height: '160px',
            alwaysVisible: true,
            color: '#333'
        })
   
</body>

</html>