首页 > 解决方案 > Bootstrap 在桌子上冻结头

问题描述

我试图冻结我的 html 表 (thead) 中的第一行,但是当我尝试以下 CSS 代码时:

table {
    width: 100% !important;
}

thead, tbody {
    display: block;
}

tr:after {
    content: ' ';
    display: block;
    visibility: hidden;
    clear: both;
}

thead th {
    height: 30px;
}

tbody {
    height: 500px;
    overflow-y: auto;
}

thead 的大小与 tbody 的大小不同。tbody 可以滚动到thead 处于固定位置,但不一样,tr 被捆绑在一起。这是我的 HTML:

<table id="MVCGridTable_Grid" class="table table-striped table-bordered">
    <thead>
        <tr>
            <th>aaa</th>
            <th>aaa</th>
            <th>aaa</th>
            <th>aaa</th>
            <th>aaa</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
        </tr>
        <tr>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
        </tr>
        <tr>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
        </tr>
        <tr>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
        </tr>
        <tr>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
            <td>
                aaa
            </td>
        </tr>
    </tbody>
</table>

这是我试图放在一起的DEMO ,但我添加的Bootstrap似乎不起作用,所以请原谅缺乏样式:

这是我得到的结果:

在此处输入图像描述

标签: htmlcsstwitter-bootstrap

解决方案


为此,您需要将表格包装在一个元素position: relative中或者,如果您愿意,可以使用以下 CSS:heightmax-heightcalc()max-heightth/td<thead>sticky-top

position: sticky;
top: 0;
z-index: 1020;

看到它工作:

"use strict";

var stickySituation = function stickySituation(o) {
  return $("".concat(o, " .sticky-top")).css('position') === 'fixed';
};

var updateStickyHeader = function updateStickyHeader(i, e) {
  var cell = $("tbody tr>*:nth-child(".concat(i + 1, ")"), $(e).closest('table')).eq(0)[0];

  if (cell) {
    var box = cell.getBoundingClientRect();
    $(e).css({
      top: 0,
      width: box.width,
      height: box.height,
      left: box.left
    });
  }
};

$(window).on('load', function () {
  var sh = '.table-responsive.sticky-headers';
  $('thead th').addClass('sticky-top bg-white');

  if (stickySituation(sh)) {
    $(sh).css({
      paddingTop: $('tbody tr>*:nth-child(1)', sh).eq(0).css('height')
    });
    $(window).on('resize', function () {
      $('thead th').each(updateStickyHeader);
    });
    $(window).trigger('resize');
  }
});
.table-responsive {
  max-height: 100vh;
  /* whatever makes sense */
  overflow-y: auto;
}

.table-responsive .sticky-top {
  border-top: 0;
  border-bottom: 0;
  box-shadow: 0 1px 0 0 gainsboro;
  /* hack for IE: */ position: fixed;
  position: sticky;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>

<div class="table-responsive position-relative sticky-headers">
  <table class="table table-striped">
    <thead>
      <tr>
        <th scope="col">#</th>
        <th scope="col">First</th>
        <th scope="col">Last</th>
        <th scope="col">Handle</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th scope="row">1</th>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <th scope="row">2</th>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <th scope="row">3</th>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <th scope="row">4</th>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <th scope="row">5</th>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <th scope="row">6</th>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <th scope="row">7</th>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <th scope="row">8</th>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <th scope="row">9</th>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
    </tbody>
  </table>
</div>

更新:为不支持position: sticky(即:IE)的浏览器添加了 JS。
现代浏览器只需要23来自脚本的行(它只向每个添加sticky-topbg-white<th>,这显然可以手动完成)。
也就是说,您实际上并不需要现代浏览器中的 JS 部分才能使其工作(只要您将类(或 CSS 规则)应用于您的标记,如上所述)。


推荐阅读