Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Table fixed header and scrollable body

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>
like image 205
giulio Avatar asked Jan 16 '14 17:01

giulio


People also ask

How do I make my table scrollable with fixed header?

Create a Table That Has a Fixed Header. We can create an HTML table that has a fixed header with some CSS. We set the height of the table element to 120px to make restrict the height of it so we can make it scrollable. To make it scrollable, we set the overflow CSS property to scroll .

How do I keep my table header fixed while scrolling in HTML?

To freeze the row/column we can use a simple HTML table and CSS. HTML: In HTML we can define the header row by <th> tag or we can use <td> tag also. Below example is using the <th> tag. We also put the table in DIV element to see the horizontal and vertical scrollbar by setting the overflow property of the DIV element.


2 Answers

Fixed table head - CSS-only

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

.tableFixHead          { overflow: auto; height: 100px; } .tableFixHead thead th { position: sticky; top: 0; z-index: 1; }  /* 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>

For both sticky vertical TH and horizontal TH columns (inside TBODY):

.tableFixHead          { overflow: auto; height: 100px; width: 240px; } .tableFixHead thead th { position: sticky; top: 0; z-index: 1; } .tableFixHead tbody th { position: sticky; left: 0; } 

.tableFixHead          { overflow: auto; height: 100px; width: 240px; } .tableFixHead thead th { position: sticky; top: 0; z-index: 1; } .tableFixHead tbody th { position: sticky; left: 0; }  /* Just common table stuff. Really. */ table  { border-collapse: collapse; width: 100%; } th, td { padding: 8px 16px; white-space: nowrap; } th     { background:#eee; }
<div class="tableFixHead">   <table>     <thead>       <tr><th></th><th>TH 1</th><th>TH 2</th></tr>     </thead>     <tbody>             <tr><th>Foo</th><td>Some long text lorem ipsum</td><td>Dolor sit amet</td></tr>             <tr><th>Bar</th><td>B1</td><td>B2</td></tr>             <tr><th>Baz</th><td>C1</td><td>C2</td></tr>             <tr><th>Fuz</th><td>D1</td><td>D2</td></tr>             <tr><th>Zup</th><td>E1</td><td>E2</td></tr>     </tbody>   </table> </div>

TH borders problem fix

Since border cannot be painted properly on a translated TH element, to recreate and render "borders" use the box-shadow property:

/* Borders (if you need them) */ .tableFixHead, .tableFixHead td {   box-shadow: inset 1px -1px #000; } .tableFixHead th {   box-shadow: inset 1px 1px #000, 0 1px #000; } 

.tableFixHead          { overflow: auto; height: 100px; } .tableFixHead thead th { position: sticky; top: 0; z-index: 1; }  /* Just common table stuff. Really. */ table  { border-collapse: collapse; width: 100%; } th, td { padding: 8px 16px; } th     { background:#eee; }  /* Borders (if you need them) */ .tableFixHead, .tableFixHead td {   box-shadow: inset 1px -1px #000; } .tableFixHead th {   box-shadow: inset 1px 1px #000, 0 1px #000; }
<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. (IE)

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) ); 
like image 109
Roko C. Buljan Avatar answered Oct 07 '22 19:10

Roko C. Buljan


Likely you'll get multiple tables on one page, therefore you need CSS classes. Please find a modified @giulio's solution for that.

Just declare it in table:

<table class="table table-striped header-fixed"></table> 

CSS

.header-fixed {     width: 100%  }  .header-fixed > thead, .header-fixed > tbody, .header-fixed > thead > tr, .header-fixed > tbody > tr, .header-fixed > thead > tr > th, .header-fixed > tbody > tr > td {     display: block; }  .header-fixed > tbody > tr:after, .header-fixed > thead > tr:after {     content: ' ';     display: block;     visibility: hidden;     clear: both; }  .header-fixed > tbody {     overflow-y: auto;     height: 150px; }  .header-fixed > tbody > tr > td, .header-fixed > thead > tr > th {     width: 20%;     float: left; } 

Be aware that current implementation suits five columns only. If you need a different number, change the width parameter from 20% to *100% / number_of_columns*.

like image 41
Alex Klaus Avatar answered Oct 07 '22 17:10

Alex Klaus