Bootstrap layout with fixed-navbar. Having table with so many rows in body.

Issue? As i scroll the page navigation-bar will be there because it is fixed. as i scroll more i want table header to be fixed under navigation-bar and the content of table(table-body) scrolls without scroll bar!

Something like This - Codepen


**Fiddle ** Bootstrap table


Working Fiddle after referring to the answer!


HTML


<!-- Wrap all page content here --> <div> <!-- Fixed navbar --> <div> <div> <div> <button type="button"> <span></span> <span></span> <span></span> </button> <a href="#">Project name</a> </div> <div> <ul> <li><a href="#">Home</a></li> <li><a href="#about">About</a></li> <li><a href="#contact">Contact</a></li> <li> <a href="#">Dropdown <b></b></a> <ul> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li></li> <li>Nav header</li> <li><a href="#">Separated link</a></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> </div><!--/.nav-collapse --> </div> </div> <!-- Begin page content --> <div> <div> <h1>Sticky footer with fixed navbar</h1> </div> <p>Pin a fixed-height footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS. A fixed navbar has been added within <code>#wrap</code> with <code>padding-top: 60px;</code> on the <code>.container</code>.</p> </div> <table> <thead> <tr> <th>#</th> <th>First Name</th> <th>Last Name</th> <th>Username</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> </tbody> </table> </div> <div> <div> <p>Example courtesy <a href="">Martin Bean</a> and <a href="">Ryan Fait</a>.</p> </div> </div> 
9

11 Answers

This can now be done without JS, just pure CSS. So, anyone trying to do this for modern browsers should look into using position: sticky instead.

Currently, both Edge and Chrome have a bug where position: sticky doesn't work on thead or tr elements, however it's possible to use it on th elements, so all you need to do is just add this to your code:

th { position: sticky; top: 50px; /* 0px if you don't have a navbar, but something is required */ background: white; } 

Note: you'll need a background color for them, or you'll be able to see through the sticky title bar.

This has very good browser support.

Demo with your code (HTML unaltered, above 5 lines of CSS added, all JS removed):

body { padding-top:50px; } table.floatThead-table { border-top: none; border-bottom: none; background-color: #fff; } th { position: sticky; top: 50px; background: white; }
<link rel="stylesheet" type="text/css" href="//"> <!-- Fixed navbar --> <div> <div> <div> <button type="button"> <span></span> <span></span> <span></span> </button> <a href="#">Project name</a> </div> <div> <ul> <li><a href="#">Home</a> </li> <li><a href="#about">About</a> </li> <li><a href="#contact">Contact</a> </li> <li> <a href="#">Dropdown <b></b></a> <ul> <li><a href="#">Action</a> </li> <li><a href="#">Another action</a> </li> <li><a href="#">Something else here</a> </li> <li></li> <li>Nav header</li> <li><a href="#">Separated link</a> </li> <li><a href="#">One more separated link</a> </li> </ul> </li> </ul> </div> <!--/.nav-collapse --> </div> </div> <!-- Begin page content --> <div> <div> <h1>Sticky Table Headers</h1> </div> <p>If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p> <p>If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p> <p>If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p> <table> <thead> <tr> <th>#</th> <th>First Name</th> <th>Last Name</th> <th>Username</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> </tbody> </table> <p>If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p> <p>If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p> <p>If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p> <p>If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p> <p>If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p> <p>If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p> <p>If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p> <h3>Table 2</h3> <table> <thead> <tr> <th>#</th> <th>New Table</th> <th>Last Name</th> <th>Username</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> </tbody> </table> </div>
6

Use:

Docs:

$(document).ready(function(){ $(".sticky-header").floatThead({top:50}); }); 

DEMO with 2 Tables and Fixed Header:


HTML

<!-- Fixed navbar --> <div> <div> <div> <button type="button"> <span></span> <span></span> <span></span> </button> <a href="#">Project name</a> </div> <div> <ul> <li><a href="#">Home</a></li> <li><a href="#about">About</a></li> <li><a href="#contact">Contact</a></li> <li> <a href="#">Dropdown <b></b></a> <ul> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li></li> <li>Nav header</li> <li><a href="#">Separated link</a></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> </div> <!--/.nav-collapse --> </div> </div> <!-- Begin page content --> <div> <div> <h1>Sticky footer with fixed navbar</h1> </div> <p>Pin a fixed-height footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS. A fixed navbar has been added within <code>#wrap</code> with <code>padding-top: 60px;</code> on the <code>.container</code>.</p> <table> <thead> <tr> <th>#</th> <th>First Name</th> <th>Last Name</th> <th>Username</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> </tbody> </table> <h3>Table 2</h3> <table> <thead> <tr> <th>#</th> <th>New Table</th> <th>Last Name</th> <th>Username</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> </tbody> </table> </div> 

CSS

body{ padding-top:50px; } table.floatThead-table { border-top: none; border-bottom: none; background-color: #fff; } 
6

You can do it easily with puse CSS without any kind of JS. you have to add position: sticky; top: 0; z-index:999; in table th . But this won't work on Chrome Browser but other browser. To work on chrome you have to add those code in table thead th

.table-fixed { width: 100%; } /*This will work on every browser but Chrome Browser*/ .table-fixed thead { position: sticky; position: -webkit-sticky; top: 0; z-index: 999; background-color: #000; color: #fff; } /*This will work on every browser*/ .table-fixed thead th { position: sticky; position: -webkit-sticky; top: 0; z-index: 999; background-color: #000; color: #fff; }
<table> <thead> <tr> <th>Table Header 1</th> <th>Table Header 2</th> <th>Table Header 3</th> </tr> </thead> <tbody> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> </tbody> </table>
4

Anyone looking for this functionality past 2018: it's much cleaner to do this with just CSS using position: sticky.

position: sticky doesn't work with some table elements (thead/tr) in Chrome. You can move sticky to tds/ths of tr you need to be sticky. Like this:

thead tr:nth-child(1) th { background: white; position: sticky; top: 0; z-index: 10; } 
0

I faced the same issue and as majority of the answers indicated, you have to apply position: sticky; and top: 0; ( mostly but can vary if there is a navbar which is fixed as well) to 'th' element. These properties do not apply to thead or tr.

One more thing, if it still doesn't work, you have to look for 'overflow' properties of the parent. If any parent component has an overflow set, i.e. overflow: hidden, then position: sticky just doesn't work. Make sure to remove all such parent properties. Chao!

5
.contents { width: 50%; border: 1px solid black; height: 300px; overflow: auto; } table { position: relative; } th { position: sticky; top: 0; background: #ffffff; }
<link rel="stylesheet" href="" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <div> <table> <thead> <tr> <th>colunn 1</th> <th>colunn 2</th> <th>colunn 3</th> <th>colunn 4</th> </tr> </thead> <tbody> <tr> <td>Example 1</td> <td>Example 2</td> <td>Example 3</td> <td>Example 4</td> <tr> <tr> <td>Example 1</td> <td>Example 2</td> <td>Example 3</td> <td>Example 4</td> <tr> <tr> <td>Example 1</td> <td>Example 2</td> <td>Example 3</td> <td>Example 4</td> <tr> <tr> <td>Example 1</td> <td>Example 2</td> <td>Example 3</td> <td>Example 4</td> <tr> <tr> <td>Example 1</td> <td>Example 2</td> <td>Example 3</td> <td>Example 4</td> <tr> <tr> <td>Example 1</td> <td>Example 2</td> <td>Example 3</td> <td>Example 4</td> <tr> <tr> <td>Example 1</td> <td>Example 2</td> <td>Example 3</td> <td>Example 4</td> <tr> <tr> <td>Example 1</td> <td>Example 2</td> <td>Example 3</td> <td>Example 4</td> <tr> <tr> <td>Example 1</td> <td>Example 2</td> <td>Example 3</td> <td>Example 4</td> <tr> <tr> <td>Example 1</td> <td>Example 2</td> <td>Example 3</td> <td>Example 4</td> <tr> </tbody> </table> </div>
2

Here is a jsfiddle HERE (not created by me) that does what you are looking for with pure css in a table. The thing to note here is the th header is set to a height of 0. Inside each th is and absolute positioned div that puts the header above the table and the scollable div that the table is in.

<thead> <tr> <th>#<div>#</div></th> <th>First Name<div>First Name</div></th> <th>Last Name<div>Last Name</div></th> <th>Username<div>Username</div></th> </tr> </thead> 
2

I accomplished something similar using jQuery Waypoints.

There's a lot of moving parts, and quite a bit of logic (that I hope to get on GitHub some day soon), but essentially what you could do is...

  1. Duplicate the table DOM structure in JavaScript and add a class called fixed.
  2. Add styles for table.fixed that make it invisible.
  3. Set a way point at the bottom of the header navigation that adds a class called sticky to table.fixed
  4. Add styles for table.sticky.fixed that position it just below the navbar and also make just the thead content visible. This also has a z-index so it is laid above the rest of the content.
  5. Add another waypoint, but in the downward scroll event, that removes .sticky from the table.fixed

You have to duplicate the entire table DOM in order to ensure column widths line up appropriately.

If that sounds really complicated, you might want to try playing around with the DataTables plugin and the FixedHeader extension:

1

Okku's post worked for me in Edge. In order to get desired result on the iPhone, I had to use:

<thead> 

which didn't effect Edge.

If you want to have an affix on your header you can use this tricks, add position: relative on your th and change the position in eventListener('scroll')

I have created an example:

I use vue.js but you can use this, without vue.js

1

For anyone looking for a modern JS framework support like ReactJS or Vue try this one instead . Which supports overflow layout.

I'm using this one on my Svelte project.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.