100%宽度的HTML表格,tbody内部有垂直滚动条

我怎样才能设置<table> 100%的宽度,并只放在<tbody>垂直滚动一些高度?

tbody内的垂直滚动

 table { width: 100%; display:block; } thead { display: inline-block; width: 100%; height: 20px; } tbody { height: 200px; display: inline-block; width: 100%; overflow: auto; } 
 <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 。

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

由于我们改变了tbodydisplay属性,我们也应该改变这个属性,以防止破坏表格布局。

所以我们有:

 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浏览器tbodytheadtbody元素显示为row-grouptable-header-grouptable-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)

tbody内的垂直滚动

工作演示

全宽表,相对宽度列

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

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

由于表格具有(sorting) stream体布局 ,所以当容器resize时,我们应该调整添加的列的宽度。

因此,一旦窗口被resize,我们应该设置列的宽度:

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

输出将是:

流体表与tbody内的垂直滚动

工作演示


浏览器支持和select

我已经通过主要的Web浏览器(包括IE10 +)的新版本在Windows 7上testing了上述两个方法,并且工作。

但是,它不能 正常 工作 在IE9及以下。

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

通过使用display: block; 对于<thead><tbody>元素,我们打破了表结构。

通过JavaScript重新devise布局

一种方法是重新devise(整个)表格布局。 使用JavaScript来即时创build新的布局,并dynamic地处理和/或调整单元格的宽度/高度。

例如,看看下面的例子:

  • jQuery .floatThead()插件(浮动/locking/粘贴表头插件)
  • jQuery可滚动表格插件。 ( 源代码在github上)
  • jQuery .FixedHeaderTable()插件(github上的源代码 )
  • DataTables 垂直滚动的例子。

嵌套表

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

CSS Play上检查垂直滚动表 。

这适用于大多数网页浏览器。 我们也可以通过JavaScriptdynamic地执行上述逻辑。

滚动上带有固定标题的表格

由于将垂直滚动条添加到<tbody>是在每行顶部显示表格标题 ,所以我们可以将thead元素的位置fixed在屏幕的顶部。

这是Julien执行的这个方法的一个工作演示
它有一个有前途的网页浏览器支持。

这里是Willem Van Bockstal的一个纯CSS实现。


纯粹的CSS解决scheme

这是旧的答案。 当然,我已经添加了一个新的方法,并改进了CSS声明。

固定宽度的表

在这种情况下, table应该有一个固定的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 */ } 

这是输出:

固定宽度的表

工作演示

表100%的宽度

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

而且,我们需要减小垂直滚动条宽度的值。

为了做到这一点,我们需要使用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; } 

这里是在线演示

注意:如果每一列的内容打破了这条线,这种方法就会失败 ,即每个单元格的内容应该足够短


下面是我在回答这个问题时创build的纯CSS解决scheme的两个简单示例。

这是jsFiddle Demo v2

旧版本: jsFiddle Demo v1

在以下解决scheme中,表占用父容器的100%,不需要绝对大小。 这是纯CSS,使用flex布局。

以下是它的外观: 在这里输入图像描述

可能的缺点:

  • 垂直滚动条总是可见的,不pipe是否需要;
  • 表格布局是固定的 – 列不根据内容宽度resize(你仍然可以设置任何明确的列宽);
  • 有一个绝对大小 – 滚动条的宽度,这是我能够检查的浏览器大约0.9em。

HTML(缩写):

 <div class="table-container"> <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> </div> 

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

 .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上

相同的代码在很less,所以你可以混合在:

 .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 forad和tbody。 因为这个列的宽度与tbody列的宽度不同。

table {margin:0 auto; border-collapse:collapse;} thead {background:#CCCCCC;display:block} tbody {height:10em;overflow-y:scroll;display:block}

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

 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中不起作用

 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); } 
  table {margin:0 auto; border-collapse:separate;} thead {background:#CCCCCC;display:block} tbody {height:10em;overflow-y:scroll;display:block} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <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> 

相继创build两个表格,将第二个表格放在固定高度的div中,并将overflow属性设置为auto。 还要把第二张桌子里的所有的td都放空。

 <div> <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> </div> <div style="max-height:500px;overflow:auto;"> <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> </div> 

我按照以下说明正确使用纯CSS:

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

第一步是将<tbody>设置为display:block,这样就可以应用溢出和高度。 从那里,需要将<thead>的行设置为position:relative和display:block,以便它们位于现在可滚动的<tbody>顶部。

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

因为<thead>是相对定位的,所以每个表单元格都需要一个明确的宽度

 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; } 

但不幸的是这还不够。 当一个滚动条出现的时候,浏览器为它分配空间,因此<tbody>结束的空间比<thead> 注意这造成了轻微的错位

唯一的解决办法是设置一个除最后一列以外的所有列的最小宽度。

 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; } 

下面的整个codepen示例:

CSS:

 .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:

 <!-- IE < 10 does not like giving a tbody a height. The workaround here applies the scrolling to a wrapped <div>. --> <!--[if lte IE 9]> <div class="old_ie_wrapper"> <!--<![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]> </div> <!--<![endif]--> 

编辑:替代解决scheme表宽度100%(以上实际上是固定宽度,并没有回答问题):

HTML:

 <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:

 table { width: 100%; text-align: left; min-width: 610px; } tr { height: 30px; padding-top: 10px } tbody { height: 150px; overflow-y: auto; overflow-x: hidden; } th,td,tr,thead,tbody { display: block; } td,th { float: left; } td:nth-child(1), th:nth-child(1) { width: 20%; } td:nth-child(2), th:nth-child(2) { width: 20%; float: left; } td:nth-child(3), th:nth-child(3) { width: 59%; float: left; } /* some colors */ thead { background-color: #333333; color: #fdfdfd; } table tbody tr:nth-child(even) { background-color: #dddddd; } 

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

Css变通办法迫使列正确显示一个'块'tbody

这个解决scheme仍然需要通过jQuery来计算和设置宽度

 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

 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 

尝试下面的方法, 很容易实现

下面是jsfiddle链接

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

HTML:

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

CSS:

  #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的:

  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) 

在使tbodythead显示块完美工作之后td添加一个固定的宽度,同时我们还可以使用slimscroll插件使滚动条变得美观。

在这里输入图像描述

 <!DOCTYPE html> <html> <head> <title> Scrollable table </title> <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> <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-slimScroll/1.3.8/jquery.slimscroll.min.js"></script> <script> $('.example-table tbody').slimscroll({ height: '160px', alwaysVisible: true, color: '#333' }) </script> </body> </html>