4

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;
}
Adrian Taylor
  • 544
  • 1
  • 5
  • 14
  • 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. `
    ` `` `` `
    ` `` `` `
    ` `` `` `
    ` `
    `
    – Korgrue Mar 14 '16 at 22:28

2 Answers2

1

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>
Prasad Kudalkar
  • 221
  • 2
  • 5
  • This is not a good solution because the columns in the two tables will not size together as they would in a normal table. – nrkn Oct 02 '18 at 02:47
  • Somehow we need to fix the widths of all cells to come up with a fixed header with scrollable rows. – Prasad Kudalkar Aug 01 '19 at 18:49
0

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

nrkn
  • 1,752
  • 3
  • 15
  • 24