3
votes

I'm having trouble achieving a fixed header scroll-able table which contains multiple tbody elements.

Basically, I'd like to put a table inside a container element of fixed size. I'd then like to scroll through any overflowing table elements, without the headers moving.

The table needs to be styled with twitter-bootstrap, but I'm not sure that's relevant to the question

Hope that makes sense!

Here is a fiddle (obviously not quite working as intended yet) https://jsfiddle.net/whbbwv7g/

And the code:

<div id="tableContainer">
    <table class="table table-bordered table-hover">
        <thead>
            <tr>
                <th>Head 1</th>
                <th>Head 2</th>
                <th>Head 3</th>
                <th>Head 4</th>
            </tr>
        </thead>


            <tbody>            
                <tr>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>                
                </tr>
                <tr>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td> 
                </tr>
                <tr>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td> 
                </tr>
            </tbody>
            <tbody>            
                <tr>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>                
                </tr>
                <tr>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td> 
                </tr>
                <tr>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td> 
                </tr>
            </tbody>
            <tbody>            
                <tr>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>                
                </tr>
                <tr>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td> 
                </tr>
                <tr>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td>
                    <td>Test</td> 
                </tr>
            </tbody>


    </table> 
</div>

The only css is:

#tableContainer {
    width: 300px;
    height:150px;
}
2
Have you tried stacking two tables on top of eachother in a div, and only using the TH elements in the top table - fix its position, and set the overflow to scroll on the bottom table. <div> <table class="toptable"> <!--put table headers here--> </table> <table class="toptable"> <!--put table headers here--> </table> <table class="bottomtable"> <!--put table rows here and set this table to overflow:scroll;--> </table> </div> - Korgrue

2 Answers

1
votes

You can divide your headers and body into separate tables. The top level table will only have the headers as you can assign the scrollable properties for the content table.

A working fiddle: https://jsfiddle.net/psk11/mjxb6vcr/

<table>
  <thead>
    <tr>
      <th>Column 1</th>
      <th>Column 2</th>
      <th>Column 3</th>
    </tr>
  </thead>
</table

<table style="height:300px;display:block;overflow-y:auto;">
  <tbody>
    <tr>
      <td>
        Row 1 Col 1
      </td>
      <td>
        Row 1 Col 2
      </td>
      <td>
        Row 1 Col 3
      </td>
    </tr>
  </tbody>

  <tbody>
    <tr>
      <td>
        Row 2 Col 1
      </td>
      <td>
        Row 2 Col 2
      </td>
      <td>
        Row 2 Col 3
      </td>
    </tr>
  </tbody>


</table>
0
votes

This has been solved elsewhere:

Freeze the top row for an html table only (Fixed Table Header Scrolling)

In brief, the solution is to use position: sticky on the th - this is what I use:

table thead th {
  position: sticky;
  position: -webkit-sticky;
  top: 0;
  z-index: 999;
}

Here's a link to caveats and support for sticky:

https://caniuse.com/#feat=css-sticky