表头固定,可滚动体水平和垂直,可变单元格宽度

时间:2018-02-14 13:17:55

标签: html css html-table scrollable

我意识到这个问题在Stack Overflow上有很多问题;然而,在仔细研究了其中一些之后,我相信我的问题还有一个要求。我想将一个常规的html表转换为一个可以垂直和水平滚动的表,同时标题是固定的。我的项目中的表是动态生成的,因此单元格宽度无法修复。

问题:

  • 向左和向右滚动时,表格会滚动,但标题会被切断
  • 标题和正文单元格宽度不适合

这是一个向您展示我的问题的JSFiddle

JSFiddle

表示例:

<div class="table-responsive">
  <table id="vehicleTable" class="table pointer hover table-striped table-bordered" role="grid">
    <thead>
      <tr>
        <th>Firstname</th>
        <th>Lastname</th> 
        <th>Age</th>
        <th>Gender</th>
        <th>Size</th> 
        <th>Mass</th>
        <th>Eyecolor</th>
        <th>Style</th> 
        <th>Shoe</th>
        <th>Sport</th>
        <th>Social Media</th>
      </tr>
     </thead>
     <tbody>
       <tr>
         <td>Jill</td>
         <td>Smith</td> 
         <td>50</td>
         <td>Female</td>
         <td>1.60</td> 
         <td>60</td>
         <td>Green</td>
         <td>Cool</td> 
         <td>New Balance</td>
         <td>Football</td> 
         <td>Facebook</td>
       </tr>
       <tr>
         <td>Anthony</td>
         <td>Meyer</td> 
         <td>34</td>
         <td>Male</td>
         <td>1.84</td> 
         <td>88</td>
         <td>Blue</td>
         <td>Elegant</td> 
         <td>All stars</td>
         <td>Golf</td> 
         <td>Facebook</td>
      </tr>
      <tr>
         <td>Eve</td>
         <td>Jackson</td> 
         <td>94</td>
         <td>Female</td>
         <td>1.58</td> 
         <td>55</td>
         <td>Green</td>
         <td>Cool</td> 
         <td>Adidas</td>
         <td>Chess</td>
         <td>Instagram</td>
      </tr>
      <tr>
         <td>Jill</td>
         <td>Smith</td> 
         <td>50</td>
         <td>Female</td>
         <td>1.60</td> 
         <td>60</td>
         <td>Green</td>
         <td>Cool</td> 
         <td>New Balance</td>
         <td>Chess</td>
         <td>Instagram</td>
       </tr>
       <tr>
         <td>Anthony</td>
         <td>Meyer</td> 
         <td>34</td>
         <td>Male</td>
         <td>1.84</td> 
         <td>88</td>
         <td>Blue</td>
         <td>Elegant</td> 
         <td>All stars</td>
         <td>Chess</td>
         <td>Instagram</td>
      </tr>
      <tr>
         <td>Eve</td>
         <td>Jackson</td> 
         <td>94</td>
         <td>Female</td>
         <td>1.58</td> 
         <td>55</td>
         <td>Green</td>
         <td>Cool</td> 
         <td>Adidas</td>
         <td>Chess</td>
         <td>Instagram</td>
      </tr>
      <tr>
         <td>Anthony</td>
         <td>Meyer</td> 
         <td>34</td>
         <td>Male</td>
         <td>1.84</td> 
         <td>88</td>
         <td>Blue</td>
         <td>Elegant</td> 
         <td>All stars</td>
         <td>Golf</td> 
         <td>Facebook</td>
      </tr>
      <tr>
         <td>Eve</td>
         <td>Jackson</td> 
         <td>94</td>
         <td>Female</td>
         <td>1.58</td> 
         <td>55</td>
         <td>Green</td>
         <td>Cool</td> 
         <td>Adidas</td>
         <td>Chess</td>
         <td>Instagram</td>
      </tr>
      <tr>
         <td>Jill</td>
         <td>Smith</td> 
         <td>50</td>
         <td>Female</td>
         <td>1.60</td> 
         <td>60</td>
         <td>Green</td>
         <td>Cool</td> 
         <td>New Balance</td>
         <td>Chess</td>
         <td>Instagram</td>
       </tr>
       <tr>
         <td>Anthony</td>
         <td>Meyer</td> 
         <td>34</td>
         <td>Male</td>
         <td>1.84</td> 
         <td>88</td>
         <td>Blue</td>
         <td>Elegant</td> 
         <td>All stars</td>
         <td>Chess</td>
         <td>Instagram</td>
      </tr>
      <tr>
         <td>Eve</td>
         <td>Jackson</td> 
         <td>94</td>
         <td>Female</td>
         <td>1.58</td> 
         <td>55</td>
         <td>Green</td>
         <td>Cool</td> 
         <td>Adidas</td>
         <td>Chess</td>
         <td>Instagram</td>
      </tr>
      <tr>
         <td>Jill</td>
         <td>Smith</td> 
         <td>50</td>
         <td>Female</td>
         <td>1.60</td> 
         <td>60</td>
         <td>Green</td>
         <td>Cool</td> 
         <td>New Balance</td>
         <td>Chess</td>
         <td>Instagram</td>
       </tr>
       <tr>
         <td>Anthony</td>
         <td>Meyer</td> 
         <td>34</td>
         <td>Male</td>
         <td>1.84</td> 
         <td>88</td>
         <td>Blue</td>
         <td>Elegant</td> 
         <td>All stars</td>
         <td>Chess</td>
         <td>Instagram</td>
      </tr>
      <tr>
         <td>Eve</td>
         <td>Jackson</td> 
         <td>94</td>
         <td>Female</td>
         <td>1.58</td> 
         <td>55</td>
         <td>Green</td>
         <td>Cool</td> 
         <td>Adidas</td>
         <td>Chess</td>
         <td>Instagram</td>
      </tr>
     </tbody>
  </table>
</div>

CSS:

table#vehicleTable {
    position: relative;
    display: block;
    margin-left: 0px;
    width: 400px;
  height: 400px;
    table-layout: fixed;
}
table#vehicleTable thead {
    position: relative;
    display: block; /*seperates the header from the body allowing it to be positioned*/
  width: inherit;
    overflow-y: hidden;
  overflow-x: hidden;
    background-color: blue;
  color: white;
}
table#vehicleTable tbody {
    position: relative;
    display: block; /*seperates the tbody from the header*/
    width: inherit;
    max-height: 400px;
    height: 400px;
    overflow-y: scroll;
    overflow-x: scroll;
}
.table-responsive {
    display: block;
    height: 400px;
    table-layout: fixed;
}
table#vehicleTable td, table#vehicleTable thead th {
    table-layout: fixed;
}

JQuery的:

$(document).ready(function () {
        $('tbody').scroll(function (e) { 
            $('thead').css("left", -$("tbody").scrollLeft());
            $('thead th div:nth-child(1)').css("left", $("tbody").scrollLeft());
            $('tbody td:nth-child(1)').css("left", $("tbody").scrollLeft());
        });
    });

1 个答案:

答案 0 :(得分:1)

编辑处理更长列的可能性,因为我没有注意到先决条件

有趣的问题!

如果您愿意为列设置固定宽度,则可以少用html, body{ height:100%; } body{ background-image:url('/sample/img/linedpaper.png'); background-repeat:repeat; background-attachment:scroll; background-position:center; } @media print{ body{ margin: 6mm; height:100vh; } #container{ width:100%; height: 100%; margin:0px auto 0 auto; } } @page { margin: 0mm; size: A4 portrait; height: 100%; } 而不是CSS来实现您想要的效果:

如果您确保设置CSS以使默认列宽与任何表标题一样长,那么此解决方案应该有效:

<强> CSS

jQuery

<强>的jQuery

table#vehicleTable {
  position: relative;
  display: block;
  margin-left: 0px;
  width: 400px;
  height: 400px;
  overflow-x: scroll;
  overflow-y: hidden;
}
table#vehicleTable thead {
  background-color: blue;
  color: white;
}
table#vehicleTable tbody {
  position: relative;
  display: inline-block;
  height: 345px; /*allowing for scrollbar and th height */
  overflow-y: scroll;
}
table#vehicleTable td, table#vehicleTable th  {
  min-width: 100px; /*suitable width for all column headers in the example*/
}

/*Added this just to handle the 2nd column, which needs to be smaller, as per comments */

table#vehicleTable td:nth-of-type(2), table#vehicleTable th:nth-of-type(2) {
  min-width: 30px;
  text-align: center;
}

这将循环遍历$(window).on('load', function () { $i = 0; $("#vehicleTable tbody tr:first-of-type td").each(function() { $i++; width = $(this).outerWidth(); $("#vehicleTable thead th:nth-of-type(" +$i+")").css({"min-width": width+"px"}); }); }); 的{​​{1}},并获取每列的相应宽度。如果您没有首先在其上设置row,那么数据短于列标题的任何列都将导致该列缩小,而标题本身仍将展开以适合其自己的内容。

同时更新JSFiddle