Table fixed header and scrollable body

2019-01-01 02:49发布

I am trying to make a table with fixed header and a scrollable content using the bootstrap 3 table. Unfortunately the solutions I have found does not work with bootstrap or mess up the style.

Here there is a simple bootstrap table, but for some reason to me unknown the height of the tbody is not 10px.

height: 10px !important; overflow: scroll;

Example:

<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">

<table class="table table-striped">
    <thead>
    <tr>
        <th>Make</th>
        <th>Model</th>
        <th>Color</th>
        <th>Year</th>
    </tr>
    </thead>
    <tbody style="height: 10px !important; overflow: scroll; ">
    <tr>
        <td class="filterable-cell">111 Ford</td>
        <td class="filterable-cell">Escort</td>
        <td class="filterable-cell">Blue</td>
        <td class="filterable-cell">2000</td>
    </tr>
    <tr>
        <td class="filterable-cell">Ford</td>
        <td class="filterable-cell">Escort</td>
        <td class="filterable-cell">Blue</td>
        <td class="filterable-cell">2000</td>
    </tr>
            <tr>
        <td class="filterable-cell">Ford</td>
        <td class="filterable-cell">Escort</td>
        <td class="filterable-cell">Blue</td>
        <td class="filterable-cell">2000</td>
    </tr>
     <tr>
        <td class="filterable-cell">Ford</td>
        <td class="filterable-cell">Escort</td>
        <td class="filterable-cell">Blue</td>
        <td class="filterable-cell">2000</td>
    </tr>
    </tbody>
    
</table>

16条回答
明月照影归
2楼-- · 2019-01-01 03:20

Here is the working solution

HTML

<table class="table table-striped">
    <thead>
        <tr>
            <th>Make</th>
            <th>Model</th>
            <th>Color</th>
            <th>Year</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="filterable-cell">Ford</td>
            <td class="filterable-cell">Escort</td>
            <td class="filterable-cell">Blue</td>
            <td class="filterable-cell">2000</td>
        </tr>
        <tr>
            <td class="filterable-cell">Ford</td>
            <td class="filterable-cell">Escort</td>
            <td class="filterable-cell">Blue</td>
            <td class="filterable-cell">2000</td>
        </tr>
        <tr>
            <td class="filterable-cell">Ford</td>
            <td class="filterable-cell">Escort</td>
            <td class="filterable-cell">Blue</td>
            <td class="filterable-cell">2000</td>
        </tr>
        <tr>
            <td class="filterable-cell">Ford</td>
            <td class="filterable-cell">Escort</td>
            <td class="filterable-cell">Blue</td>
            <td class="filterable-cell">2000</td>
        </tr>
    </tbody>
</table>

CSS

table {
    width: 100%;
}

thead, tbody, tr, td, th { display: block; }

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

thead th {
    height: 30px;

    /*text-align: left;*/
}

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

thead {
    /* fallback */
}


tbody td, thead th {
    width: 19.2%;
    float: left;
}

Link to jsfiddle

查看更多
梦该遗忘
3楼-- · 2019-01-01 03:20

You can place two div where 1st div (Header) will have transparent scroll bar and 2nd div will be have data with visible/auto scroll bar. Sample has angular code snippet for looping through the data.

Below code worked for me -

<div id="transparentScrollbarDiv" class="container-fluid" style="overflow-y: scroll;">
    <div class="row">
        <div class="col-lg-3 col-xs-3"><strong>{{col1}}</strong></div>
        <div class="col-lg-6 col-xs-6"><strong>{{col2}}</strong></div>
        <div class="col-lg-3 col-xs-3"><strong>{{col3}}</strong></div>
    </div>
</div>
<div class="container-fluid" style="height: 150px; overflow-y: auto">
    <div>
        <div class="row" ng-repeat="row in rows">
            <div class="col-lg-3 col-xs-3">{{row.col1}}</div>
            <div class="col-lg-6 col-xs-6">{{row.col2}}</div>
            <div class="col-lg-3 col-xs-3">{{row.col3}}</div>
        </div>
    </div>
</div>

Additional style to hide header scroll bar -

<style>
        #transparentScrollbarDiv::-webkit-scrollbar {
            width: inherit;
        }

        /* this targets the default scrollbar (compulsory) */

        #transparentScrollbarDiv::-webkit-scrollbar-track {
            background-color: transparent;
        }

        /* the new scrollbar will have a flat appearance with the set background color */

        #transparentScrollbarDiv::-webkit-scrollbar-thumb {
            background-color: transparent;
        }

        /* this will style the thumb, ignoring the track */

        #transparentScrollbarDiv::-webkit-scrollbar-button {
            background-color: transparent;
        }

        /* optionally, you can style the top and the bottom buttons (left and right for horizontal bars) */

        #transparentScrollbarDiv::-webkit-scrollbar-corner {
            background-color: transparent;
        }

        /* if both the vertical and the horizontal bars appear, then perhaps the right bottom corner also needs to be styled */
    </style>
查看更多
浮光初槿花落
4楼-- · 2019-01-01 03:20

For whatever it's worth now: I did post a solution to a sister-thread Table scroll with HTML and CSS which

  • takes two tables (one for only header, one for all - layouted by the browser)
  • after layouting, adjust the upper (header-only) table to the widths of the lower one
  • hide (visibility, not display) the header of the lower table and make the lower table scrollable w/in a div

The solution is agnostic to any styles / frameworks used - so maybe it's useful here as well...

A long description is in Table scroll with HTML and CSS / the code is also in this pen: https://codepen.io/sebredhh/pen/QmJvKy

查看更多
看淡一切
5楼-- · 2019-01-01 03:25

You should try with "display:block;" to tbody, because now it's inline-block and in order to set height, the element should be "block"

查看更多
公子世无双
6楼-- · 2019-01-01 03:26

I am using StickyTableHeaders on GitHub and it works like charm!

I had to add this css to make the header not transparent though.

table#stickyHeader thead {
  border-top: none;
  border-bottom: none;
  background-color: #FFF;
}
查看更多
何处买醉
7楼-- · 2019-01-01 03:27

Fixed table head - CSS-only

Simply position: sticky; top: 0; your th elements. (Chrome, FF, Edge)

.tableFixHead    { overflow-y: auto; height: 100px; }
.tableFixHead th { position: sticky; top: 0; }

/* Just common table stuff. Really. */
table  { border-collapse: collapse; width: 100%; }
th, td { padding: 8px 16px; }
th     { background:#eee; }
<div class="tableFixHead">
  <table>
    <thead>
      <tr><th>TH 1</th><th>TH 2</th></tr>
    </thead>
    <tbody>
      <tr><td>A1</td><td>A2</td></tr>
      <tr><td>B1</td><td>B2</td></tr>
      <tr><td>C1</td><td>C2</td></tr>
      <tr><td>D1</td><td>D2</td></tr>
      <tr><td>E1</td><td>E2</td></tr>
    </tbody>
  </table>
</div>


Fixed table head - using JS

You can use a bit of JS and translateY the th elements

jQuery example

var $th = $('.tableFixHead').find('thead th')
$('.tableFixHead').on('scroll', function() {
  $th.css('transform', 'translateY('+ this.scrollTop +'px)');
});
.tableFixHead { overflow-y: auto; height: 100px; }

/* Just common table stuff. */
table  { border-collapse: collapse; width: 100%; }
th, td { padding: 8px 16px; }
th     { background:#eee; }
<div class="tableFixHead">
  <table>
    <thead>
      <tr><th>TH 1</th><th>TH 2</th></tr>
    </thead>
    <tbody>
      <tr><td>A1</td><td>A2</td></tr>
      <tr><td>B1</td><td>B2</td></tr>
      <tr><td>C1</td><td>C2</td></tr>
      <tr><td>D1</td><td>D2</td></tr>
      <tr><td>E1</td><td>E2</td></tr>
    </tbody>
  </table>
</div>

<script src="https://code.jquery.com/jquery-3.1.0.js"></script>

Or plain ES6 if you prefer (no jQuery required):

// Fix table head
function tableFixHead (e) {
    const el = e.target,
          sT = el.scrollTop;
    [...el.querySelectorAll("thead th")].forEach(th => 
       th.style.transform = `translateY(${sT}px)`;
    );
}
[...document.querySelectorAll(".tableFixHead")].forEach(el => 
    el.addEventListener("scroll", tableFixHead)
);
查看更多
登录 后发表回答