具有固定位置和可滚动表数据元素的 HTML 表头

Posted

技术标签:

【中文标题】具有固定位置和可滚动表数据元素的 HTML 表头【英文标题】:HTML Table Header with Fixed Position and scroll able table data elements 【发布时间】:2017-03-26 17:57:13 【问题描述】:

这个问题的主要目的是固定表格标题,当我们垂直滚动时,只有元素应该滚动并且表格标题应该在同一位置

我希望这样做 无需手动固定表头的宽度,因为我的列标题宽度取决于 td 元素。我看到一些问题,其中使用手动固定宽度找到了解决方案表头。

有人可以通过使用相同的 CSS 类名来帮助我解决这个问题

下面是我的桌子的Demo。

Demo Of the Table

我在上表中使用的 CSS

.wrapper 

overflow : auto;
width: 1350px;
max-height : 250px;
white-space: nowrap;
padding-bottom : 10px;
padding-top : 10px;

.professional .title 
    padding-top: 10px;
    backgrounionad: #2980b9;

td 
white-space: nowrap;
border-style: solid;
padding: 8px;
border-right-color: #ff0000;


th 
position:auto;
text-align: center;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
width : auto;
height : word-spacing;
white-space: nowrap;



.table 

width: auto;
max-width: auto;
margin-bottom: 20px;


.tableheader 

-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
font-size: 1.3rem;
border-radius: 5px;
text-transform: capitalize;
position: relative;

padding: 10px 25px 10px 25px;

【问题讨论】:

如果您对 jquery 解决方案持开放态度,这应该会有所帮助。 codepen.io/jgx/pen/wiIGc 谢谢,但我试过我需要修复我的 css 才能使用 jquery。 【参考方案1】:

您可以做的,不是使用表格行作为标题,而是创建一个 <div> 元素并将其设置为位于屏幕顶部

#tableheader 
    position:fixed;
    top:0;
    width:100%;
    z-index:100;

然后你可以在它下面放一个表格元素。

<div id="tableheader">
Table title
</div>
<table>
    <tr>
        <td>Data</td>
        <td>More Data</td>
    </tr>
</table>

【讨论】:

这对我不起作用,你能帮我在演示中编辑我的 CSS【参考方案2】:

你可以这样做:

将第一行放入&lt;thead&gt;&lt;/thead&gt; 并添加css position:fixed; 将表格的其余部分放入&lt;tbody&gt;&lt;/tbody&gt; 并添加css top: 3em; position:relative; top 的值取决于您的字体大小。

如果您没有水平滚动条,这将起作用。

.wrapper 
    overflow: auto;
    width: 1350px;
    max-height: 250px;
    white-space: nowrap;
    padding-bottom: 10px;
    padding-top: 10px;

.professional .title 
    padding-top: 10px;
    background: #2980b9;


td 
    white-space: nowrap;
    border-style: solid;
    padding: 8px;
    border-right-color: #ff0000;

th 
    position: auto;
    text-align: center;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
    width: auto;
    height: word-spacing;
    white-space: nowrap;

.table 
    width: auto;
    max-width: auto;
    margin-bottom: 20px;

.tableheader 
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
    font-size: 1.3rem;
    border-radius: 5px;
    text-transform: capitalize;
    position: relative;
    padding: 10px 25px 10px 25px;

tbody
  top:3em;
  position:relative;

thead 
  position:fixed;
<link rel="stylesheet" href="style.css" />
   <body>
      Scrollable Table
      <div class="wrapper">
      
        <table class="professional">
          <thead>
            <tr>
                  <th class="tableheader">Message ID</th>
                  <th class="tableheader">Operation</th>
                  <th class="tableheader">Status</th>
                  <th class="tableheader">Send Time</th>
                  <th class="tableheader">Receive Time</th>
                  <th class="tableheader">Send Data</th>
                  <th class="tableheader">Receive Data</th>
               </tr>
               </thead>
            <tbody>
            
               <!-- ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e66982cf7857fee2cb5</td>
                  <td class="ng-binding">Operation1</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">null</td>
                  <td class="ng-binding">2016-11-09 18:32:30</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e681b58b970137b56aa</td>
                  <td class="ng-binding">Operation2</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:32</td>
                  <td class="ng-binding">2016-11-09 18:32:32</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e691b58b970137b56ab</td>
                  <td class="ng-binding">Operation3</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e691b58b970137b56ab</td>
                  <td class="ng-binding">Operation3</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e691b58b970137b56ab</td>
                  <td class="ng-binding">Operation3</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e691b58b970137b56ab</td>
                  <td class="ng-binding">Operation3</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e691b58b970137b56ab</td>
                  <td class="ng-binding">Operation3</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e691b58b970137b56ab</td>
                  <td class="ng-binding">Operation3</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e691b58b970137b56ab</td>
                  <td class="ng-binding">Operation3</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e691b58b970137b56ab</td>
                  <td class="ng-binding">Operation3</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e691b58b970137b56ab</td>
                  <td class="ng-binding">Operation3</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e6d1b58b970137b56ac</td>
                  <td class="ng-binding">Operation4</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:33</td>
                  <td class="ng-binding">2016-11-09 18:32:37</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e721b58b970137b56ad</td>
                  <td class="ng-binding">Operation5</td>
                  <td class="ng-binding">FAILURE</td>
                  <td class="ng-binding">2016-11-09 18:32:37</td>
                  <td class="ng-binding">null</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e731b58b970137b56ae</td>
                  <td class="ng-binding">Operation6</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:43</td>
                  <td class="ng-binding">2016-11-09 18:32:43</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e741b58b970137b56af</td>
                  <td class="ng-binding">Operation7</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:43</td>
                  <td class="ng-binding">2016-11-09 18:32:44</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e761b58b970137b56b0</td>
                  <td class="ng-binding">Operation8</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:46</td>
                  <td class="ng-binding">2016-11-09 18:32:46</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e771b58b970137b56b1</td>
                  <td class="ng-binding">Operation9</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:46</td>
                  <td class="ng-binding">2016-11-09 18:32:47</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e781b58b970137b56b2</td>
                  <td class="ng-binding">Operation10</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:47</td>
                  <td class="ng-binding">2016-11-09 18:32:48</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e791b58b970137b56b3</td>
                  <td class="ng-binding">Operation11</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:32:48</td>
                  <td class="ng-binding">2016-11-09 18:32:49</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e8d982cf7857fee2cb9</td>
                  <td class="ng-binding">Operation1</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">null</td>
                  <td class="ng-binding">2016-11-09 18:33:09</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
               <tr class="features ng-scope" ng-repeat="list in opMessageLogs">
                  <td class="ng-binding">58231e97a782de0c9ea24979</td>
                  <td class="ng-binding">Operation2</td>
                  <td class="ng-binding">SUCCESS</td>
                  <td class="ng-binding">2016-11-09 18:33:19</td>
                  <td class="ng-binding">2016-11-09 18:33:19</td>
                  <td ng-click="showText(list.REQUEST,$index)">Request</td>
                  <td ng-click="showText(list.RESPONSE,$index)">Response</td>
               </tr>
               <!-- end ngRepeat: list in opMessageLogs -->
            </tbody>
         </table>
      </div>
   </body>

【讨论】:

实际上我的表格可能会根据内容大小扩展到右侧。有什么方法可以做到水平滚动 我已经创建了新的 Jsfiddler 添加我的整个 CSS,如果你有时间可以请你更新那个 CSS,我认为它因为其他一些依赖它不起作用Demo 好吧,我认为水平滚动是不可能的。如果您在 css 中修复一个元素,它将水平和垂直固定。对于您的实际代码:thead position: fixed; // Fix your thead so it won't move z-index: 40; // This way, your thead will be over your tbody 您还应该删除 #wrapper padding-top:10px; 感谢您抽出宝贵的时间,我终于可以通过手动修复宽度来进行管理了。 @Kangouroops,我尝试使用上面的解决方案。似乎正在工作。但是我们怎样才能让表格中的数据向下滚动到表头,而不是在滚动时看到表头的顶部。【参考方案3】:

如果您只想将标题的宽度与 td 元素的宽度相匹配,您可以使用 javascript offsetWidth 来实现。 这将为您提供 td 元素的宽度。所以你可以使用你看到的答案固定表格标题的宽度

如果您不想使用 javascript ,也许这会对您有所帮助:

    .wrapper 
        display:inline-block;
        position:relative;
    
    .tableheader
        display:block;
    
    .tablebody
        display:block;
        overflow-y:scroll;
        max-height:80px;
    
    .ng-binding
        display:block;
    
<div class="wrapper">
    <div class="tableheader">
        Message ID
    </div>
    <div class="tablebody">
        <div class="ng-binding">
            58231e66982cf7857fee2cb5
        </div>
        <div class="ng-binding">
            58231e66982cf7857fee2cb5
        </div>
        <div class="ng-binding">
            58231e66982cf7857fee2cb5
        </div>
        <div class="ng-binding">
            58231e66982cf7857fee2cb5
        </div>
        <div class="ng-binding">
            58231e66982cf7857fee2cb5
        </div>
        <div class="ng-binding">
            58231e66982cf7857fee2cb5
        </div>
        <div class="ng-binding">
            58231e66982cf7857fee2cb5
        </div>
        <div class="ng-binding">
            58231e66982cf7857fee2cb5
        </div>
    </div>
</div>
<div class="wrapper">
    <div class="tableheader">
        Operation
    </div>
    <div class="tablebody">
        <div class="ng-binding">
            Operation1
        </div>
        <div class="ng-binding">
            Operation2
        </div>
        <div class="ng-binding">
            Operation3
        </div>
        <div class="ng-binding">
            Operation11
        </div>
        <div class="ng-binding">
            5Operation12
        </div>
        <div class="ng-binding">
            Operation13
        </div>
        <div class="ng-binding">
            Operation14
        </div>
        <div class="ng-binding">
            Operation15
        </div>
    </div>
</div>

【讨论】:

我不想有独立的滚动条,有没有我只能为此制作一个垂直滚动条。 可能有一种方法可以在没有 javascript 的情况下执行此操作,但我找不到它。【参考方案4】:

最后我手动修复了表格宽度,但在这里我做了下面的事情以使其按我想要的方式工作。

最初我手动找到了最大单元格内容的宽度。在不触及 CSS 的情况下,我覆盖了 html 本身的宽度,如下所示。

由于在我的实际应用程序中我使用的是 ng-repeat,因此我不需要在每一行中手动添加这些。

任何改进/建议总是被接受:)

style="width : 183px !important;"

Working Demo

注意:请在放大窗口中查看演示,如下所示

我的应用程序 HTML 使用 Ng-Repeat

<div>
            <!--, From the local table,-->
            <table class="professional">
                <tbody>
                    <thead>
                        <tr>

                            <th class="tableheader" style="width : 183px !important;">Message ID</th>
                            <th class="tableheader" style="width : 353px !important;">Operation</th>
                            <th class="tableheader" style="width : 88px !important;">Status</th>
                            <th class="tableheader" style="width : 153px !important;">Account Number</th>
                            <th class="tableheader" style="width : 130px !important;">Send Time</th>
                            <th class="tableheader" style="width : 130px !important;">Receive Time</th>
                            <th class="tableheader" style="width : 113px !important;">Send Data</th>
                            <th class="tableheader" style="width : 128px !important;">Receive Data</th>

                        </tr>
                    </thead>
                </tbody>
            </table>
        </div>
        <div class="wrapper">
            <table class="professional">
                <tbody>

                    <tr class="features" ng-repeat="list in mesaages">
                        <td style="width : 183px !important;">list._id.$id</td>
                        <td style="width : 353px !important;">list.OPERATION</td>
                        <td style="width : 88px !important;">list.STATUS</td>
                        <td style="width : 153px !important;">list.ACCOUNTNUMBER</td>
                        <td style="width : 130px !important;">list.SENDTIME.sec * 1000 | date:'yyyy-MM-dd HH:mm:ss'</td>
                        <td  style="width : 130px !important;">list.RECEIVETIME.sec * 1000 | date:'yyyy-MM-dd HH:mm:ss'</td>
                        <td ng-click="showText(list.REQUEST,$index)" style="width : 113px !important;"><a style="cursor: pointer;">Request</a></td>
                        <td ng-click="showText(list.RESPONSE,$index)" style="width : 128px !important;"><a style="cursor: pointer;">Response</a></td>
                    </tr>

                </tbody>

            </table>
        </div>

【讨论】:

【参考方案5】:

试试这个代码:

.container
  width:100%;
  height:150px;
  overflow:auto;

td
border:1px solid;

.header
  width:calc(100% - 17px);
  width:-webkit-calc(100% - 17px);
  width:-moz-calc(100% - 17px);
 height:25px; 
 background:#000;color:#fff;
<table class="header">
<tr >
  <td >header</td>
  <td >header</td>
  </tr>
</table>
<div class="container">
<table style="width:100%; ">
<tr >
  <td >body</td>
  <td >body</td>
  </tr>
  <tr >
  <td >body</td>
  <td >body</td>
  </tr>
  <tr >
  <td >body</td>
  <td >body</td>
  </tr>
  <tr >
  <td >body</td>
  <td >body</td>
  </tr>
  <tr >
  <td >body</td>
  <td >body</td>
  </tr>
   <tr >
  <td >body</td>
  <td >body</td>
  </tr>
   <tr >
  <td >body</td>
  <td >body</td>
  </tr>
   <tr >
  <td >body</td>
  <td >body</td>
  </tr>
   <tr >
  <td >body</td>
  <td >body</td>
  </tr>
   <tr >
  <td >body</td>
  <td >body</td>
  </tr>
</table>
</div>

【讨论】:

以上是关于具有固定位置和可滚动表数据元素的 HTML 表头的主要内容,如果未能解决你的问题,请参考以下文章

Flexbox 类型的固定表头,表格标记的可滚动内容

html中怎么固定一个table的表头和表位,拖动滚动条中间的数据滚动,而表头和表尾固定呢?表尾是用来做合计

表格固定标题和可滚动正文

el-table固定多列问题

实现固定表头和表列的table组件

实现固定表头和表列的table组件