简体   繁体   English

具有固定页眉和页脚以及没有固定宽度的可滚动正文的 HTML 表格

[英]HTML table with fixed header and footer and scrollable body without fixed widths

I want to to create a table with fixed thead and tfoot and a scrollable tbody !我想创建一个带有固定的theadtfoot以及一个可滚动的tbody的表格!

I've tried several approaches, both CSS only and CSS + Javascript, but they are all weak and unreliable and I can easily break them by changing the markup in the demo.我尝试了几种方法,包括仅 CSS 和 CSS + Javascript,但它们都很弱且不可靠,我可以通过更改演示中的标记轻松破坏它们。

What I want is a way to have the table to behave like a table , this means that the browser will automatically adjust columns based on the content (both at page load that in case of window resize) and that in these scenarios:我想要的是一种让表格表现得像表格的方法,这意味着浏览器将根据内容自动调整列(在页面加载时调整窗口大小)以及在这些情况下:

  1. if the content of the column's header ( thead > tr > th ) is larger than the content of the column's body ( tbody > tr > td ) and larger than the content of the column's footer ( tfoot > tr > td ) the column should resize based on the size of the column's header如果列标题的内容 ( thead > tr > th ) 大于列正文的内容 ( tbody > tr > td ) 并且大于列尾的内容 ( tfoot > tr > td ),则列应调整大小基于列标题的大小

  2. if the content of the column's body ( tbody > tr > td ) is larger than the content of the column's header ( thead > tr > th ) and larger than the content of the column's footer ( tfoot > tr > td ) the column should resize based on the size of the column's body如果列正文的内容 ( tbody > tr > td ) 大于列标题的内容 ( thead > tr > th ) 并且大于列尾的内容 ( tfoot > tr > td ),则列应调整大小基于列主体的大小

  3. if the content of the column's footer ( tfoot > tr > td ) is larger than the content of the column's header ( thead > tr > th ) and larger than the content of the column's body ( tbody > tr > td ) the column should resize based on the size of the column's footer如果列页脚的内容 ( tfoot > tr > td ) 大于列标题的内容 ( thead > tr > th ) 并且大于列正文的内容 ( tbody > tr > td ),则列应调整大小基于列页脚的大小

The table below should clarify the scenarios:table应阐明情景:

<table>
  <thead>
    <tr>
      <th>Header one *leads the width* (case 1)</th>
      <th>Header two</th>
      <th>Header three</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>Footer one</td>
      <td>Footer two</td>
      <td>Footer three *leads the width* (case 3)</td>
    </tr>
  </tfoot>
</table>

I want a clean (as possible) and reliable solution that will work for the different scenarios, possibly CSS only but also JavaScript is OK (vanilla and clean JavaScript, not jQuery plugins).我想要一个干净(尽可能)和可靠的解决方案,可以适用于不同的场景,可能只有 CSS,但 JavaScript 也可以(香草和干净的 JavaScript,而不是 jQuery 插件)。 I don't care about old browser support (it would be great to have it or at least to reach a solution which can degrade gracefully on old browser but it's optional)... I can even accept to use div s instead of table nodes if the final solution works as expected... so in 2016, with modern browser and CSS is this possible somehow?!我不关心旧浏览器的支持(拥有它或者至少能找到一个可以在旧浏览器上优雅降级但它是可选的解决方案会很棒)......我什至可以接受使用div s而不是表节点如果最终解决方案按预期工作......那么在 2016 年,使用现代浏览器和 CSS 有可能以某种方式实现吗?!

EDIT:编辑:

The body should scroll vertically and the table may have any number of columns正文应该垂直滚动,表格可以有任意数量的列

UPDATE:更新:

I came up with this solution: https://codepen.io/daveoncode/pen/LNomBE but I'm still not 100% satisfied.我想出了这个解决方案: https ://codepen.io/daveoncode/pen/LNomBE 但我仍然不是 100% 满意。 The main issue is that I can't set different backgrounds for header and footer cells.主要问题是我无法为页眉和页脚单元格设置不同的背景。

UPDATE 2:更新 2:

it works now!现在可以了!

HTML table with fixed header and footer and scrollable body without fixed widths using CSS only .仅使用 CSS 具有固定页眉和页脚以及没有固定宽度的可滚动正文的 HTML 表格

This is simple logic we can use table header put position: sticky method below the example:这是一个简单的逻辑,我们可以在示例下方使用表头 put position:sticky方法:

table th {
position:sticky;
top: 0;
}

UPDATE 2022 2022 年更新

Nowadays and for awhile browsers have full support for position: sticky现在和一段时间的浏览器完全支持position: sticky

So we can apply it to thead th and tfoot tr所以我们可以将它应用到thead thtfoot tr

 body { margin: 0 } table { width: 100% } thead th, tfoot tr { position: sticky; background: red } thead th { top: 0 } tfoot tr { bottom: 0 } th, td { font-size: 12px; text-align: center } /*give some space between thead and tfoot*/ tbody tr:first-of-type td { padding-top: 10px; } tbody tr:last-of-type td { padding-bottom: 10px; }
 <table> <thead> <tr> <th>Header one *leads the width* (case 1)</th> <th>Header two</th> <th>Header three</th> </tr> </thead> <tbody> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> </tbody> <tfoot> <tr> <td>Footer one</td> <td>Footer two</td> <td>Footer three *leads the width* (case 3)</td> </tr> </tfoot> </table>

OLD Answer旧答案

you can achieve what you want by using a wrapper to your table ( div ) and make the tr from thead and tfoot a position:absolute您可以通过对表格( div )使用包装器来实现您想要的,并使来自theadtfoottr成为一个position:absolute

 body { margin: 0 } div { max-height: 500px; overflow-y: auto; } table { width: 100% } thead tr, tfoot tr { position: absolute; left: 0; right: 15px; /* to not cover the scrollbar*/ background: red } thead th, tfoot td { display: inline-block; } thead tr { top: 0 } tfoot tr { top: 500px/* same value has max-height from div */ } th, td { width: calc((100%/3) - 5px); font-size: 12px; text-align: center } /*give some space between thead and tfoot*/ tbody tr:first-of-type td { padding-top: 35px; } tbody tr:last-of-type td { padding-bottom: 35px; }
 <div> <table> <thead> <tr> <th>Header one *leads the width* (case 1)</th> <th>Header two</th> <th>Header three</th> </tr> </thead> <tbody> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> <tr> <td>Column one</td> <td>Column two *leads the width* (case 2)</td> <td>Column three</td> </tr> </tbody> <tfoot> <tr> <td>Footer one</td> <td>Footer two</td> <td>Footer three *leads the width* (case 3)</td> </tr> </tfoot> </table> </div>

I finally implemented a working solution!我终于实施了一个可行的解决方案!

The relevant CSS is the following:相关的 CSS 如下:

.wrapper {
  width: 90%;
  position: relative;
  border: 1px solid #000;
  background: #efefef;
  overflow: hidden;
  border-radius: 7px;
}

.container {
  overflow-y: auto;
  height: 200px;
  border-top: 41px solid transparent;
  border-bottom: 41px solid transparent;
}

table {
  border-spacing: 0;
  border-collapse: collapse;
  width: 100%;
}

td + td {
  border-left: 1px solid #fff;
}

td, th {
  border-bottom: 1px solid #fff;
  background: #efefef;
  padding: 10px;
}

thead tr th,
tfoot tr td {
  height: 0;
  line-height: 0;
  margin: 0;
  padding-top: 0;
  padding-bottom: 0;
  color: transparent;
  border: none;
  white-space: nowrap;
}

thead tr th div,
tfoot tr td div {
  position: absolute;
  color: #fff;
  height: 20px;
  padding: 10px;
  margin-left: -10px;
  line-height: normal;
  width: 100%;
  z-index: 2;
  text-align: left;
  font-weight: bold;
}

thead tr th div {
  border-left: 1px solid #000;
  border-bottom: 1px solid #000;
}

tfoot tr td div {
  border-top: 1px solid #000;
}

tfoot tr td div.c1,
thead tr th div.c1 {
  background: violet;
}

tfoot tr td div.c2,
thead tr th div.c2 {
  background: green;
}

tfoot tr td div.c3,
thead tr th div.c3 {
  background: yellow;
}

thead tr th div {
  top: 0;
}

tfoot tr td div {
  bottom: 0;
}

thead tr th:first-child div,
tfoot tr td:first-child div {
  border-left: none;
}

And this is the markup:这是标记:

<div class="wrapper">
  <div class="container">
    <table>
      <thead>
        <tr>
          <th>
            Header one *leads the width* (case 1)
            <div class="c1">
              Header one *leads the width* (case 1)
            </div>
          </th>
          <th>
            Header two
            <div class="c2">
              Header two
            </div>
          </th>
          <th>
            Header three
            <div class="c3">
              Header three
            </div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three [first]</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three [LATEST]</td>
        </tr>
      </tbody>
      <tfoot>
        <tr>
          <td>
            Footer one
            <div class="c1">
              Footer one
            </div>
          </td>
          <td>
            Footer two
            <div class="c2">Footer two</div>
          </td>
          <td>
            Footer three *leads the width* (case 3)
            <div class="c3">Footer three *leads the width* (case 3)</div>
          </td>
        </tr>
      </tfoot>
    </table>
  </div>
</div>

It works on Chrome, Firefox, Safari and IE11 (I don't know how it behaves on older browsers).它适用于 Chrome、Firefox、Safari 和 IE11(我不知道它在旧浏览器上的表现如何)。 See it on codepen: https://codepen.io/daveoncode/pen/LNomBE在 codepen 上查看: https ://codepen.io/daveoncode/pen/LNomBE

$.ajax({
          url: "upload.php",
          type: "POST",
          data: fd,
          processData: false,  // tell jQuery not to process the data
          contentType: false   // tell jQuery not to set contentType
        }).done(function( data ) {
            console.log("PHP Output:");
            console.log( data );
        });
        return false;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM