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 为单位固定宽度。

原文由 Marko S 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 927
2 个回答

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

由于我们更改了 display tbody ,我们应该更改 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 browsers display the thead and tbody elements as row-group ( table-header-group and table-row-group ) by default.

一旦我们改变它,内部 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 */
}

由于表格具有(某种) 流体布局,我们应该在容器调整大小时调整 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

输出将是:

在 tbody 内有垂直滚动的 Fluid Table

工作演示


浏览器支持和替代品

我已经在Windows 7上通过新版本的主要网络浏览器(包括IE10+)测试了上述两种方法,并且有效。

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

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

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

通过 JavaScript 重新设计布局

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

例如,看看下面的例子:

嵌套表

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

检查 CSS Play 中的 垂直滚动表

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

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

由于向 <tbody> 添加垂直滚动条的目的是在每一行的顶部显示表 ,我们可以 thead 元素放置到 fixed 而不是在屏幕的顶部。

这是 Julien 执行的这种方法的 工作演示

它有一个很有前途的网络浏览器支持。

这里Willem Van Bockstal纯 CSS 实现。


纯 CSS 解决方案

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

固定宽度的表格

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

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

因此,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% 宽度的表格

In this approach, the table has a width of 100% and for each th and td , the value of width 属性应小于 100% / number of cols

此外,我们需要减少 thead宽度 作为垂直滚动条的 宽度 值。

为此,我们需要使用 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;
}

这是 在线演示

注意: 如果每列的内容都断行,即 每个单元格的内容要足够短, 这种方法就会 失败


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

这是 jsFiddle 演示 v2

旧版本: jsFiddle Demo v1

原文由 Hashem Qolami 发布,翻译遵循 CC BY-SA 3.0 许可协议

在下面的解决方案中,表占据父容器的 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;
}

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

原文由 tsayen 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏