【问题标题】:HTML table with fixed header and footer and scrollable body without fixed widths具有固定页眉和页脚以及没有固定宽度的可滚动正文的 HTML 表格
【发布时间】:2016-09-13 07:54:56
【问题描述】:

我想创建一个带有固定theadtfoot 以及可滚动tbody 的表!

我尝试了几种方法,包括纯 CSS 和 CSS + Javascript,但它们都很弱且不可靠,我可以通过更改演示中的标记轻松打破它们。

我想要的是一种让表格表现得像表格的方法,这意味着浏览器将根据内容自动调整列(都在页面在窗口调整大小的情况下加载)以及在这些情况下:

  1. 如果列标题 (thead > tr > th) 的内容大于列正文 (tbody > tr > td) 的内容并且大于列脚的内容 (tfoot > tr > td),则列应调整大小基于列标题的大小

  2. 如果列正文 (tbody > tr > td) 的内容大于列标题 (thead > tr > th) 的内容并且大于列脚的内容 (tfoot > tr > td),则列应调整大小基于列体的大小

  3. 如果列的页脚内容 (tfoot > tr > td) 大于列标题的内容 (thead > tr > th) 并且大于列正文的内容 (tbody > tr > td),则列应调整大小基于列页脚的大小

下面的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>

我想要一个干净(尽可能)和可靠的解决方案,可以适用于不同的场景,可能只有 CSS,但 JavaScript 也可以(vanilla 和干净的 JavaScript,而不是 jQuery 插件)。 我不关心旧浏览器的支持(拥有它或者至少能找到一个可以在旧浏览器上优雅降级的解决方案,但它是可选的)......我什至可以接受使用divs 而不是如果最终解决方案按预期工作,则表节点......那么在 2016 年,使用现代浏览器和 CSS 是否可能以某种方式实现?!

编辑:

正文应该垂直滚动,表格可以有任意数量的列

更新:

我想出了这个解决方案:https://codepen.io/daveoncode/pen/LNomBE 但我仍然不是 100% 满意。主要问题是我无法为页眉和页脚单元格设置不同的背景。

更新 2:

现在可以使用了!

【问题讨论】:

标签: javascript html css html-table


【解决方案1】:

仅使用 CSS 具有固定页眉和页脚以及不固定宽度的可滚动正文的 HTML 表格

这是一个简单的逻辑,我们可以在示例下方使用表头放置 position:sticky 方法:

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

【讨论】:

  • 页脚的单元格底部需要一个额外的锚点:bottom: 0;
【解决方案2】:

您可以通过对表使用包装器 (div) 来实现您想要的,并将 trtheadtfoot 变成 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>

【讨论】:

  • 您的示例不起作用,请参见此处:codepen.io/daveoncode/pen/VaOWgO?editors=1100#anon-login 此外,您将宽度分配给 tds (33%),但该方法应该始终有效(即使对于具有 4、10、50 列的表格)
  • 我只能滚动 tbodydiv,如果你有超过 3 列,只需计算一下,100/3 =33.3%,所以 4 列更改到 25%,100/4=25%
  • 滚动部分很容易,问题是列对齐,在您的示例中不起作用...此外,通过使用表格,浏览器通常足够聪明,可以根据内容调整列大小,这意味着我可以有一个 60% 的列和两个 20% 的列,这不是一个简单的数学除法;)
  • 如果你想连列那么这是简单的数学;),但你要找的是width:auto
【解决方案3】:
$.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;
    }

【讨论】:

    【解决方案4】:

    我终于实现了一个可行的解决方案!

    相关的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;
    }
    

    这是标记:

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

    它适用于 Chrome、Firefox、Safari 和 IE11(我不知道它在旧浏览器上的表现如何)。 在 codepen 上查看:https://codepen.io/daveoncode/pen/LNomBE

    【讨论】:

    • 如果您使窗口比表格内容更窄,则中断。不过,在大多数情况下,这可以用最小宽度来处理。
    • 也只支持text-align:left作为标题。标题中的 div 使用整个表格的 100% 宽度而不是第 th 单元格。
    • 简洁易用的 CSS 解决方案,只是缺少水平滚动。使用 javascript 可以实现页眉和页脚的水平滚动。
    • 好吧,@daveoncode 你应该问一下它是否可以在较旧的 mozillas 等上工作,因为overflow-y 是由 IE 发明的,并且将与 1997 年的 IE 或第一个符合标准的浏览器兼容市场。
    • 仅当表格小于页面宽度时才有效。否则,当您 x 滚动内容时,创建的“假”标题(固定)不会随内容移动。
    猜你喜欢
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-09
    • 2018-01-26
    • 2017-08-06
    • 1970-01-01
    相关资源
    最近更新 更多