【问题标题】:HTML table with 100% width, with vertical scroll inside tbody具有 100% 宽度的 HTML 表格,在 tbody 内具有垂直滚动 [重复]
【发布时间】:2013-06-08 16:06:47
【问题描述】:

如何设置<table> 100% 宽度并仅在<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% 宽度以像素为单位的固定宽度。

【问题讨论】:

标签: html css vertical-scrolling


【解决方案1】:

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

由于我们更改了tbodydisplay 属性,我们也应该更改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 浏览器默认将theadtbody 元素显示为行组table-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 上)

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; 用于&lt;thead&gt;&lt;tbody&gt; 元素,我们破坏了表结构。

通过 JavaScript 重新设计布局

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

例如,看看下面的例子:

嵌套表

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

CSS Play查看Vertical scrolling tables

这适用于大多数网络浏览器。我们也可以通过 JavaScript 动态地完成上述逻辑。

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

由于向&lt;tbody&gt; 添加垂直滚动条的目的是在每一行的顶部显示表格标题,我们可以定位 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%,对于每个thtdwidth 属性的值应小于100% / number of cols

另外,我们需要减小theadwidth作为垂直滚动条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

【讨论】:

  • 使用display: block,您将失去表格的属性,即在thead 和tbody 之间共享列的宽度。我知道你已经通过设置width: 19.2% 解决了这个问题,但如果我们事先不知道每列的宽度,这将不起作用。
  • 这段代码似乎假设正文单元格总是比标题单元格宽。
  • height: 100% 时不起作用(当您希望表格展开到页面底部时)。
  • 您可以使用box-sizing 属性进一步改进这一点,这样具有两种不同粗细的边框不会影响列对齐。
  • 如果你在打字稿中使用它,colWidth var 定义不起作用...需要做colWidth = $bodyCells.toArray().map(function() { return $(this).width(); }); 因为 jquery.map 返回一个 jquery 对象而不是一个数字数组
【解决方案2】:

我将display:block 用于theadtbody。 因此thead 列的宽度与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>

【讨论】:

  • 这是我发现的最好/最简单的解决方案,它允许不固定的列宽(例如 .NET DataGrid 控件)。对于“生产”,colNumber 变量可以替换为迭代找到的实际单元格的代码,并注意它不能正确处理如果有任何colspans(也可以是如有必要,对代码进行改进,但不太可能在可能需要此滚动功能的表格上)。
  • 这有效(以某种方式),但当窗口大小小于表格时(因为它忽略了滚动条宽度)就无法应对。
  • 是的,如果表格宽度限制在设定的宽度内,标题和单元格不再匹配
【解决方案3】:

按照这些说明,我终于用纯 CSS 搞定了:

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

第一步是将&lt;tbody&gt; 设置为 display: 块,以便可以应用溢出和高度。从那里开始,&lt;thead&gt; 中的行需要设置为 position: relative 和 display: block,以便它们位于现在可滚动的 &lt;tbody&gt; 之上。

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

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

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

但不幸的是,这还不够。因此,当滚动条出现时,浏览器会为其分配空间,因此,&lt;tbody&gt; 的可用空间比&lt;thead&gt; 少。注意这造成的轻微错位......

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

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

编辑:表格宽度 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

【讨论】:

  • 你不考虑单元格行内容经度
【解决方案4】:

使用“块”tbody 强制列正确显示的 Css 解决方法

此解决方案仍然需要由 jQuery 计算和设置 th 宽度

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

【讨论】:

    【解决方案5】:

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

    下面是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)
    

    【讨论】:

    • 此解决方案无法处理比表格宽度更窄的窗口。发生这种情况时,它应该启用水平滚动。此外,标题与数据单元格 (Chrome) 不完全对齐。
    【解决方案6】:

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

    它的外观如下:

    可能的缺点:

    • 无论是否需要,垂直滚动条始终可见;
    • 表格布局是固定的 - 列不会根据内容宽度调整大小(您仍然可以明确设置所需的任何列宽);
    • 有一个绝对大小 - 滚动条的宽度,对于我能够检查的浏览器来说,它约为 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;
    }
    

    full code on 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%;
        }
      }
    }
    

    【讨论】:

    • 感谢您的解决方案!有一个小错误......你为thead设置了两次宽度,我发现从宽度中减去1.05em会更好一些:jsfiddle.net/xuvsncr2/170
    • 字符的内容数呢?在 de row 单元格中添加更多字符或单词时会出现问题
    • 我认为在td 上设置一些合适的包装策略应该会有所帮助
    • 如果不想让table占据父容器100%的空间,可以尝试在table和父容器之间再添加一个容器,宽度任意设置。
    • @tsayen 如何在调整窗口大小时阻止它向上折叠和重叠?
    【解决方案7】:

    依次创建两个表,将第二个表放在一个固定高度的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>
    

    【讨论】:

    • 在这种情况下,第二个表格列不能跟随第一个表格的宽度。
    • 不好!您失去了两个表上列的宽度同步。
    • 要完成这个解决方案,我们需要添加@Hashem Qolami 脚本(describe above)来同步标题列的宽度
    【解决方案8】:

    tbody & thead 显示块后添加固定宽度到 td,th 效果很好,我们也可以使用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>

    【讨论】:

      【解决方案9】:

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

      th {
        position: sticky;
        top: 0;
        z-index: 2;
      }
      

      【讨论】:

      • 这个咒语不完整...愿意发布一个例子,或者至少详细说明一下?
      • 工作良好,但仅适用于 th。如果我们将位置设置为粘性,则它不起作用。
      • 当你用&lt;div&gt; 包裹你的&lt;table&gt; 时,这个答案有效,overflow-y: auto; 和一些max-height。例如:&lt;div style="overflow-y: auto; max-height: 400px;"&gt;&lt;table&gt;...&lt;/table&gt;&lt;/div&gt;
      • @Minwork 此处的目的是在滚动内容时保持标题固定,而不是整个表格。
      【解决方案10】:

      这是我在带有可滚动 tbody 的桌子上创建粘性头的代码:

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

      【讨论】:

        【解决方案11】:

        纯 CSS

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

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

        /* Fix table head */
        .tableFixHead    { overflow: 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; }
        <div class="tableFixHead">
          <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>
        </div>

        PS:如果您需要 TH 元素的 bordersth {box-shadow: 1px 1px 0 #000; border-top: 0;} 会有所帮助(因为默认边框在滚动时未正确绘制)。

        对于上述仅使用一点 JS 以适应 IE11 的变体,请参阅此答案 Table fixed header and scrollable body

        【讨论】:

        【解决方案12】:

        要使用“overflow:scroll”,您必须在 thead 和 tbody 上设置“display:block”。这会弄乱它们之间的列宽。但是您可以使用 Javascript 克隆 thead 行并将其作为隐藏行粘贴到 tbody 中,以保持准确的 col 宽度。

        $('.myTable thead > tr')
            .clone()
            .appendTo('.myTable tbody')
            .addClass('hidden-to-set-col-widths')
        ;
        

        http://jsfiddle.net/Julesezaar/mup0c5hk/

            <table class="myTable">
                <thead>
                    <tr>
                        <td>Problem</td>
                        <td>Solution</td>
                        <td>blah</td>
                        <td>derp</td>
                    </tr>
                </thead>
                <tbody></tbody>
            </table>
            <p>
              Some text to here
            </p>
        

        CSS:

        
            table {
              background-color: #aaa;
              width: 100%;
            }
            
            thead,
            tbody {
              display: block; // Necessary to use overflow: scroll
            }
            
            tbody {
              background-color: #ddd;
              height: 150px;
              overflow-y: scroll;
            }
            
            tbody tr.hidden-to-set-col-widths,
            tbody tr.hidden-to-set-col-widths td {
              visibility: hidden;
              height: 0;
              line-height: 0;
              padding-top: 0;
              padding-bottom: 0;
            }
            
            td {
              padding: 3px 10px;
            }
        

        【讨论】:

          【解决方案13】:

          试试这个jsfiddle。这是使用 jQuery 并根据 Hashem Qolami 的回答制作的。首先,制作一个常规表格,然后使其可滚动。

          const makeScrollableTable = function (tableSelector, tbodyHeight) {
            let $table = $(tableSelector);
            let $bodyCells = $table.find('tbody tr:first').children();
            let $headCells = $table.find('thead tr:first').children();
            let headColWidth = 0;
            let bodyColWidth = 0;
            
            headColWidth = $headCells.map(function () {
              return $(this).outerWidth();
            }).get();
            bodyColWidth = $bodyCells.map(function () {
              return $(this).outerWidth();
            }).get();
          
            $table.find('thead tr').children().each(function (i, v) {
              $(v).css("width", headColWidth[i]+"px");
              $(v).css("min-width", headColWidth[i]+"px");
              $(v).css("max-width", headColWidth[i]+"px");
            });
            $table.find('tbody tr').children().each(function (i, v) {
              $(v).css("width", bodyColWidth[i]+"px");
              $(v).css("min-width", bodyColWidth[i]+"px");
              $(v).css("max-width", bodyColWidth[i]+"px");
            });
          
            $table.find('thead').css("display", "block");
            $table.find('tbody').css("display", "block");
          
            $table.find('tbody').css("height", tbodyHeight+"px");
            $table.find('tbody').css("overflow-y", "auto");
            $table.find('tbody').css("overflow-x", "hidden");
            
          };
          

          那么你可以如下使用这个函数:

          makeScrollableTable('#test-table', 250);
          

          【讨论】:

            猜你喜欢
            • 2018-02-22
            • 2016-10-30
            • 2020-07-07
            • 2015-03-06
            • 2012-06-15
            • 1970-01-01
            • 2019-07-27
            相关资源
            最近更新 更多